我通常必须对一系列可以通过后缀(范围,假设从 _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/