Search code examples
rdplyrpipeacross

Problem while specifiyng parameters in custom function inside dplyr's across


I'm having some trouble while I'm searching to specify parameters in custom function passed to .fns argument in dplyr's across. Consider this code:

data(iris)

ref_col <- "Sepal.Length"

iris_summary <- iris %>%
  group_by(Species) %>%
  summarise(
    Sepal.Length_max = max(Sepal.Length),
    across(
      Sepal.Width:Petal.Width,
      ~ .x[which.max(get(ref_col))]
    )
  )

This works properly. Then I need to replace lambda function with a custom function and then pass requested arguments inside across (in my code the custom function is more complex and it is not convenient to be embedded in dplyr piping). See following code:

ref_col <- "Sepal.Length"

get_which_max <- function(x, col_max) x[which.max(get(col_max))]

iris_summary <- iris %>%
  group_by(Species) %>%
  summarise(
    Sepal.Length_max = max(Sepal.Length),
    across(
      Sepal.Width:Petal.Width,
      ~ get_which_max(.x, ref_col)
    )
  )

R is now giving error "object 'Sepal.Length' not found" as it is sercing for an object instead colname inside piping process. Anyone can help me to fix this problem?


Solution

  • We may either use cur_data() or pick (from the devel version of dplyr to select the column. Also, remove the get from inside the get_which_max

    get_which_max <- function(x, col_max) x[which.max(col_max)]
    
    iris_summary <- iris %>%
      group_by(Species) %>%
      summarise(
        Sepal.Length_max = max(Sepal.Length),
        across(
          Sepal.Width:Petal.Width,
          ~ get_which_max(.x, cur_data()[[ref_col]])
        )
      )
    

    -output

    # A tibble: 3 × 5
      Species    Sepal.Length_max Sepal.Width Petal.Length Petal.Width
      <fct>                 <dbl>       <dbl>        <dbl>       <dbl>
    1 setosa                  5.8         4            1.2         0.2
    2 versicolor              7           3.2          4.7         1.4
    3 virginica               7.9         3.8          6.4         2