-1

I followed this code to create the row total for the dataframe df

library(tidyverse)

df <- df %>%
  bind_rows(summarise(., across(where(is.numeric), sum),
                                across(where(is.character), ~'Total')))

If I modified the code, it would return an error

df <- df %>%
  bind_rows(summarise(across(where(is.numeric), sum),
                             across(where(is.character), ~'Total')))

# Error: `across()` must only be used inside dplyr verbs.

My question is: what does the dot . inside the summarise refer to? Why was it needed for the code to run properly? My guess was that the dot referred to the dataframe df, which was already implied by the part df %>%. This post didn't answer my question.

Nemo
  • 1,124
  • 2
  • 16
  • 39
  • 1
    I think this [post](https://stackoverflow.com/questions/35272457/what-does-the-dplyr-period-character-reference) is relevant. – benson23 Feb 09 '23 at 04:16
  • It’s hard to imagine that this has not been asked and answered before. The first thing I would try is search on “[tidyverse] meaning of dot” – IRTFM Feb 09 '23 at 04:19
  • Thanks @benson23 for the answer. I now realised that I should have included the specific term `dplyr` in my google search to find relevant info. – Nemo Feb 09 '23 at 04:28

1 Answers1

2

In magrittr, . represents the object on the left-hand side (lhs) of the pipe. By default, the lhs is passed to the first argument of the function on the rhs. But if you want to also use the lhs elsewhere in the rhs, you can use ..

In your examples,

df %>%
  bind_rows(summarise(
    across(where(is.numeric), sum),
    across(where(is.character), ~'Total')
  ))

is equivalent to

bind_rows(
  df,
  summarise(
    across(where(is.numeric), sum),
    across(where(is.character), ~'Total')
  )
)

This throws an error because summarise() expects a dataframe as its first argument. Whereas

df %>%
  bind_rows(summarise(
    .,
    across(where(is.numeric), sum),
    across(where(is.character), ~'Total')
  ))

is equivalent to

bind_rows(
  df,
  summarise(
    df,
    across(where(is.numeric), sum),
    across(where(is.character), ~'Total')
  )
)

which works.

In both cases, df is passed as the first arg to bind_rows(). In the second example, it’s also passed to summarise() due to the ..

zephryl
  • 14,633
  • 3
  • 11
  • 30