min with variable as column name

Viewed 43

I'm currently working on a project and I'm having a problem which I can't find the answer for. So this is what I'm trying to do:

df
| sex      | age      | values | nationality  | 
| -------- | -------- | ------ | ------------ | 
| male     | 18       | 3      | german       | 
| male     | 40       | 4      | italian      |   
| female   | 18       | 1      | belgian      | 
| male     | 40       | 2      | american     | 


col <- "values"
groups <- c("sex", "age")

f <- function(df, col, groups) {
  df <- df |> 
    group_by_at(groups) |> 
    filter(!!col == min(col) |> 
    ungroup()
}

# Solution I want:
f(df, col, groups)

| sex      | age      | values | nationality  | 
| -------- | -------- | ------ | ------------ | 
| male     | 18       | 3      | german       |   
| female   | 18       | 1      | belgian      | 
| male     | 40       | 2      | american     | 

The part that is giving me headaches is the use of col in the fucntion. I already found the solution to use !!col instead of col for the first use. But I can't find the solution for min(col). I already tried many things like min(!!col), min(UQ(col) and a few others.

Thanks for your help.

Ps: This is basically what my function should be doing, just with sex, age as a parameter (vector) and col as a parameter:

df <- df |>
  group_by(sex, age) |>
  filter(col == min(col)) |>
  ungroup()
1 Answers

The approach below should make your function work. To use group_by with an external vector of string variable names we can use all_of() inside across() inside group_by().

To access the values of a variable when using a string we use !! sym() and we need it on both sides of the ==.


library(dplyr)

f <- function(df, col, groups) {
  df <- df %>%
    group_by(across(all_of(groups))) %>% 
    filter(!! sym(col) == min(!! sym(col))) %>%
    ungroup()
df
}

# since the original data doesn‘t use `dput()` here a test on the mtcars data
f(mtcars, "mpg", c("am", "gear"))

# A tibble: 6 x 11
    mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1  21       6  160    110  3.9   2.62  16.5     0     1     4     4
2  21       6  160    110  3.9   2.88  17.0     0     1     4     4
3  17.8     6  168.   123  3.92  3.44  18.9     1     0     4     4
4  10.4     8  472    205  2.93  5.25  18.0     0     0     3     4
5  10.4     8  460    215  3     5.42  17.8     0     0     3     4
6  15       8  301    335  3.54  3.57  14.6     0     1     5     8


Related