r - mutate(across) 在 tidyverse 中生成多个新列

标签 r tidyverse

我通常必须对一系列可以通过后缀(范围,假设从 _a 到 _i)标识的变量/列执行等效计算,并将结果保存在新变量/列中。计算是等效的,但计算中使用的变量之间有所不同。这些又可以通过相同的后缀(_a 到 _i)来标识。所以我基本上想要实现的目标如下:

newvar_a = (oldvar1_a + oldvar2_a) - z
...
newvar_i = (oldvar1_i + oldvar2_i) - z

这是我得到的最远距离:

mutate(across(c(oldvar1_a:oldvar1_i), ~ . - z, .names = "{col}_new"))

因此,我能够“循环”oldvar1_a 到 oldvar1_i,从中减去 z 并将结果保存在名为 oldvar1_a_new 到 oldvar1_i_new 的新列中。但是,我无法将 oldvar2_a 到 oldvar2_i 包含在计算中,因为 R 不会循环遍历它们。 (此外,我仍然需要重命名新列)。

我找到了一种使用 for 循环来实现结果的方法。然而,这看起来绝对不是最有效、最直接的方法:

for (i in letters[1:9]) {
  oldvar1_x <- paste0("oldvar1_", i)
  oldvar2_x <- paste0("oldvar2_", i)
  newvar_x <- paste0("newvar_", i)
  df <- df %>%
    mutate(!!sym(newvar_x) := (!!sym(oldvar1_x) + !!sym(oldvar2_x)) - z)
}

因此,我想知道是否/如何对可以通过后缀标识的多个列进行 mutate(across) 循环(如上面的示例所示)

最佳答案

在这种情况下,您可以使用 cur_data()cur_column() 来利用我们想要将具有相同后缀但只需要的列求和在一起的优势交换数字。

library(dplyr)

df <- data.frame(
  oldvar1_a = 1:3,
  oldvar2_a = 4:6,
  oldvar1_i = 7:9,
  oldvar2_i = 10:12,
  z = c(1,10,20)
)

mutate(
  df,
  across(
    starts_with("oldvar1"),
    ~ (.x + cur_data()[gsub("1", "2", cur_column())]) - z,
    .names = "{col}_new"
  )
)
#>   oldvar1_a oldvar2_a oldvar1_i oldvar2_i  z oldvar2_a oldvar2_i
#> 1         1         4         7        10  1         4        16
#> 2         2         5         8        11 10        -3         9
#> 3         3         6         9        12 20       -11         1

如果您想与 case_when 一起使用,只需确保使用 [[ 进行索引,您可以阅读更多 here

df <- data.frame(
  oldvar1_a = 1:3,
  oldvar2_a = 4:6,
  oldvar1_i = 7:9,
  oldvar2_i = 10:12,
  z = c(1,2,0)
)

mutate(
  df,
  across(
    starts_with("oldvar1"),
    ~ case_when(
      z == 1 ~ .x,
      z == 2 ~ cur_data()[[gsub("1", "2", cur_column())]],
      TRUE ~ NA_integer_
    ),
    .names = "{col}_new"
  )
)
#>   oldvar1_a oldvar2_a oldvar1_i oldvar2_i z oldvar1_a_new oldvar1_i_new
#> 1         1         4         7        10 1             1             7
#> 2         2         5         8        11 2             5            11
#> 3         3         6         9        12 0            NA            NA

关于r - mutate(across) 在 tidyverse 中生成多个新列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70079508/

相关文章:

r - R 中的 do-while 循环

R计算具有奇点的lm模型的稳健标准误差(vcovHC)

使用跨替换 group_by_at(NULL)

r - 根据索引列创建新列

r - tidyverse:有效绑定(bind)列表元素

r - 通过多个步骤将宽数据集转变成长数据集

r - 对 R 中的经验加权分布函数执行 KS.test

r - 加载多个 .RData 并绑定(bind)到单个 data.frame 中

r - 向 lapply 函数添加第二个参数

r - 在子组内使用单一、通用的特定于组的基线进行计算(累计)