如何在 R 中将 mutate_at() 与两组变量一起使用

How to use mutate_at() with two sets of variables, in R

我想使用 dplyr 将一列除以另一列,其中两列具有相似的模式。 我有以下数据框:

My_data = data.frame(
  var_a = 101:110,
  var_b = 201:210,
  number_a = 1:10,
  number_b = 21:30)

我想创建一个新变量:var_a_new = var_a/number_a, var_b_new = var_b/number_b 如果我有 c, d 等

My_data %>%
  mutate_at(
    .vars = c('var_a', 'var_b'),
    .funs = list( new = function(x) x/(.[,paste0('number_a', names(x))]) ))

我没有得到一个错误,但是一个错误的结果。我认为问题是我不明白 'x' 是什么。它是.vars 中的字符串之一吗?它是 My_data 中的一列吗?还有别的吗?

一个选项可以是:

bind_cols(My_data,
          My_data %>%
           transmute(across(starts_with("var"))/across(starts_with("number"))) %>%
           rename_all(~ paste0(., "_new")))

   var_a var_b number_a number_b var_a_new var_b_new
1    101   201        1       21 101.00000  9.571429
2    102   202        2       22  51.00000  9.181818
3    103   203        3       23  34.33333  8.826087
4    104   204        4       24  26.00000  8.500000
5    105   205        5       25  21.00000  8.200000
6    106   206        6       26  17.66667  7.923077
7    107   207        7       27  15.28571  7.666667
8    108   208        8       28  13.50000  7.428571
9    109   209        9       29  12.11111  7.206897
10   110   210       10       30  11.00000  7.000000

您可以直接执行此操作,前提是列的顺序正确,这意味着 "var_a" 是“var”组中的第一列,"number_a" 是“number”组中的第一列,其他对依此类推.

var_cols <- grep('var', names(My_data), value = TRUE)
number_cols <- grep('number', names(My_data), value = TRUE)

My_data[paste0(var_cols, '_new')] <- My_data[var_cols]/My_data[number_cols]
My_data

#   var_a var_b number_a number_b var_a_new var_b_new
#1    101   201        1       21 101.00000  9.571429
#2    102   202        2       22  51.00000  9.181818
#3    103   203        3       23  34.33333  8.826087
#4    104   204        4       24  26.00000  8.500000
#5    105   205        5       25  21.00000  8.200000
#6    106   206        6       26  17.66667  7.923077
#7    107   207        7       27  15.28571  7.666667
#8    108   208        8       28  13.50000  7.428571
#9    109   209        9       29  12.11111  7.206897
#10   110   210       10       30  11.00000  7.000000

函数 across() 已经替换了作用域变体,例如 mutate_at()、summarize_at() 等。有关详细信息,请参阅 vignette("colwise") 或 https://cran.r-project.org/web/packages/dplyr/vignettes/colwise.html。根据 tmfmnk 的回答,以下内容效果很好:

My_data %>% 
  mutate(
    new = across(starts_with("var"))/across(starts_with("number")))

前缀“新”。将添加到新变量的名称中。

  var_a var_b number_a number_b new.var_a     new.var_b
1    101   201        1       21 101.00000      9.571429
2    102   202        2       22  51.00000      9.181818
3    103   203        3       23  34.33333      8.826087
4    104   204        4       24  26.00000      8.500000
5    105   205        5       25  21.00000      8.200000
6    106   206        6       26  17.66667  7.923077
7    107   207        7       27  15.28571  7.666667
8    108   208        8       28  13.50000  7.428571
9    109   209        9       29  12.11111  7.206897
10   110   210       10       30  11.00000  7.000000