Search code examples
rvariablesselectdplyr

dplyr: mutate new column based on multiple columns selected by variable string


Given this data:

df=data.frame(
  x1=c(2,0,0,NA,0,1,1,NA,0,1),
  x2=c(3,2,NA,5,3,2,NA,NA,4,5),
  x3=c(0,1,0,1,3,0,NA,NA,0,1),
  x4=c(1,0,NA,3,0,0,NA,0,0,1),
  x5=c(1,1,NA,1,3,4,NA,3,3,1))

I want to create an extra column min for the rowwise minimal value of selected columns using dplyr. That's easy using the column names:

df <- df %>% rowwise() %>% mutate(min = min(x2,x5))

But I have a large df with varying column names so I need to match them from some string of values mycols. Now other threads tell me to use select helper functions, but I must be missing something. Here's matches:

mycols <- c("x2","x5")
df <- df %>% rowwise() %>%
  mutate(min = min(select(matches(mycols))))
Error: is.string(match) is not TRUE

And one_of:

mycols <- c("x2","x5")
 df <- df %>%
 rowwise() %>%
 mutate(min = min(select(one_of(mycols))))
Error: no applicable method for 'select' applied to an object of class "c('integer', 'numeric')"
In addition: Warning message:
In one_of(c("x2", "x5")) : Unknown variables: `x2`, `x5`

What am I overlooking? Should select_ work? It doesn't in the following:

df <- df %>%
   rowwise() %>%
   mutate(min = min(select_(mycols)))
Error: no applicable method for 'select_' applied to an object of class "character"

And likewise:

df <- df %>%
  rowwise() %>%
  mutate(min = min(select_(matches(mycols))))
Error: is.string(match) is not TRUE

Solution

  • This was a bit trickier. In case of SE evaluation you'd need to pass the operation as string.

    mycols <- '(x2,x5)'
    f <- paste0('min',mycols)
    df %>% rowwise() %>% mutate_(min = f)
    df
    # A tibble: 10 × 6
    #      x1    x2    x3    x4    x5   min
    #   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
    #1      2     3     0     1     1     1
    #2      0     2     1     0     1     1
    #3      0    NA     0    NA    NA    NA
    #4     NA     5     1     3     1     1
    #5      0     3     3     0     3     3
    #6      1     2     0     0     4     2
    #7      1    NA    NA    NA    NA    NA
    #8     NA    NA    NA     0     3    NA
    #9      0     4     0     0     3     3
    #10     1     5     1     1     1     1