使用带有否定选择助手的mutate_at(),例如(不是one_of())

时间:2017-08-25 06:40:16

标签: r dplyr tidyverse

我的数据看起来像这样:

library(dplyr)    
set.seed(123)

df <- data_frame(X1 = rep(LETTERS[1:4], 6),
                 X2 = rep(1:2, 12),
                 ref = sample(1:50, 24),
                 sampl1 = sample(1:50, 24),
                 var2 = sample(1:50, 24),
                 meas3 = sample(1:50, 24))

使用dplyr的scooped命令,我可以一次编辑和创建多个列,例如:

df %>% mutate_if(is.numeric, funs(new = . - ref))

如果我只想对列的子集执行此操作,我可以使用select帮助程序,如下所示:

df %>% mutate_at(vars(one_of(c("X2", "ref"))), funs(new = . - ref))

但是在我的情况下,我知道我的数据将始终包含列X1X2ref,但是希望以这样的方式对数据进行子集化,以便仅对列进行变更这些不是X1X2ref。这些其他列的编号和名称将是可变的,但始终为数字。我以为我可以这样做:

df %>% mutate_at(vars(!one_of(c("X1", "X2", "ref"))), funs(new = . - ref))

或者

df %>% mutate_at(vars(one_of(!names %in% c("X1", "X2", "ref"))), funs(new = . - ref))

但是都不行。你如何做负面的dplyr select助手?

1 个答案:

答案 0 :(得分:7)

one_of需要-而非!

df %>%
   mutate_at(vars(-one_of(c("X1", "X2", "ref"))), funs(new = . - ref))
# A tibble: 24 x 9
#      X1    X2   ref sampl1  var2 meas3 sampl1_new var2_new meas3_new
#   <chr> <int> <int>  <int> <int> <int>      <int>    <int>     <int>
# 1     A     1    15     33    14    36         18       -1        21
# 2     B     2    39     35    43     1         -4        4       -38
# 3     C     1    20     27     3    23          7      -17         3
# 4     D     2    42     28    21    11        -14      -21       -31
# 5     A     1    44     14    37    18        -30       -7       -26
# 6     B     2     3      7     6    28          4        3        25
# 7     C     1    24     43    25    16         19        1        -8
# 8     D     2    49     39     9     5        -10      -40       -44
# 9     A     1    46     30    45    47        -16       -1         1
#10     B     2    19     50    31    45         31       12        26