我想编写此代码的较短版本:
ResultsTable <- ResultsTable %>%
mutate(V_a = as.integer(V_a + h2_a),
V_b = as.integer(V_b + h2_b),
V_c = as.integer(V_c + h2_c),
V_d = as.integer(V_d + h2_d),
V_e = as.integer(V_e + h2_e),
V_f = as.integer(V_f + h2_f))
有几个变量前缀和后缀需要组合。
此外,这只应针对
ResultsTable$cond == 1
的行执行此操作,但必须保留所有行。
我尝试使用 across(),但这似乎不适用于前缀和后缀。
我什至不知道如何解决这个问题。帮忙!
如果您提供可重现的示例以及预期的输出,那么帮助会更容易。这是一个简单的例子 -
df <- data.frame(cond = c(1, 1, 0, 1, 0),
V_a = 1:5, V_b = 11:15,
h2_a = 26:30, h2_b = 36:40)
df
# cond V_a V_b h2_a h2_b
#1 1 1 11 26 36
#2 1 2 12 27 37
#3 0 3 13 28 38
#4 1 4 14 29 39
#5 0 5 15 30 40
自动化此操作的一种方法是使用
across
和 pick
。为了更好地了解结果,我使用 res_V_a
中的 res_V_b
参数创建新列来存储输出(.names
和 across
)。对于这些结果列,我们检查 cond
列是 1 还是 0,并使用 ifelse
应用条件。
library(dplyr)
df %>%
mutate(across(starts_with("V"), .names = "res_{col}") + pick(starts_with("h2")),
across(starts_with("res"), ~ifelse(cond == 1, .,
get(sub("res_", "", cur_column())))))
# cond V_a V_b h2_a h2_b res_V_a res_V_b
#1 1 1 11 26 36 27 47
#2 1 2 12 27 37 29 49
#3 0 3 13 28 38 3 13
#4 1 4 14 29 39 33 53
#5 0 5 15 30 40 5 15
如果您不想创建新列并仅修改现有列。
df %>%
mutate(pick(starts_with("V")) + pick(starts_with("h2")),
across(starts_with("V"), ~ifelse(cond == 1, .,
. - get(sub("V", "h2", cur_column())))))
# cond V_a V_b h2_a h2_b
#1 1 27 47 26 36
#2 1 29 49 27 37
#3 0 3 13 28 38
#4 1 33 53 29 39
#5 0 5 15 30 40
我更喜欢在 R 基础中执行这些类型的操作。您可以编写一个辅助函数来为您执行此操作:
add_cols <- function(dat, target_prefix, to_add_prefix, suffixes) {
target_cols <- paste0(target_prefix, suffixes)
to_add_cols <- paste0(to_add_prefix, suffixes)
dat[target_cols] <- Map(
\(x, y, d = dat) d[[x]] + d[[y]],
target_cols,
to_add_cols
)
dat
}
让我们创建一个像这样的
ResultsTable
:
ResultsTable
# V_a V_b V_c V_d V_e h2_a h2_b h2_c h2_d h2_e
# 1 1 2 3 4 5 1 2 3 4 5
# 2 1 2 3 4 5 1 2 3 4 5
然后将其应用于数据。当您分配回原始列时,我们预计
V_
列会加倍:
add_cols(ResultsTable, "V_", "h2_", letters[1:5])
# V_a V_b V_c V_d V_e h2_a h2_b h2_c h2_d h2_e
# 1 2 4 6 8 10 1 2 3 4 5
# 2 2 4 6 8 10 1 2 3 4 5
如果您只想在某些行的情况下执行此操作,您可以简单地将函数应用于数据的子集并仅将其分配给这些行。
ResultsTable$cond <- 1:2 # create cond column
# Apply function to subset of data and apply conditionally
ResultsTable[ResultsTable$cond == 1, ] <- add_cols(
ResultsTable[ResultsTable$cond == 1, ],
"V_", "h2_", letters[1:5]
)
ResultsTable
# V_a V_b V_c V_d V_e h2_a h2_b h2_c h2_d h2_e cond
# 1 2 4 6 8 10 1 2 3 4 5 1
# 2 1 2 3 4 5 1 2 3 4 5 2
ResultsTable <- structure(list(V_a = c(1L, 1L), V_b = c(2L, 2L), V_c = c(3L,
3L), V_d = c(4L, 4L), V_e = c(5L, 5L), h2_a = c(1L, 1L), h2_b = c(2L,
2L), h2_c = c(3L, 3L), h2_d = c(4L, 4L), h2_e = c(5L, 5L)), row.names = 1:2, class = "data.frame")