我知道类似的问题 here和 here ,但我一直无法找出适合我的具体情况的正确解决方案。我发现的一些解决方案是使用 mutate_
等,但我知道这些现在已经过时了。我是 dplyr 动态用法的新手。
我有一个数据框,其中包含一些带有两个不同前缀 alpha 和 beta 的变量:
df <- data.frame(alpha.num = c(1, 3, 5, 7),
alpha.char = c("a", "c", "e", "g"),
beta.num = c(2, 4, 6, 8),
beta.char = c("b", "d", "f", "h"),
which.to.use = c("alpha", "alpha", "beta", "beta"))
我想创建前缀为“chosen”的新变量。它们是“alpha”或“beta”列的副本,具体取决于“which.to.use”列中该行的名称。所需的输出是:
desired.df <- data.frame(alpha.num = c(1, 3, 5, 7),
alpha.char = c("a", "c", "e", "g"),
beta.num = c(2, 4, 6, 8),
beta.char = c("b", "d", "f", "h"),
which.to.use = c("alpha", "alpha", "beta", "beta"),
chosen.num = c(1, 3, 6, 8),
chosen.char = c("a", "c", "f", "h"))
我失败的尝试:
varnames <- c("num", "char")
df %<>%
mutate(as.name(paste0("chosen.", varnames)) := case_when(
which.to.use == "alpha" ~ paste0("alpha.", varnames),
which.to.use == "beta" ~ pasteo("beta.", varnames)
))
我更喜欢纯 dplyr 解决方案,甚至更好的是可以包含在修改 df 的更长管道中的解决方案(即无需停下来创建“varnames”)。谢谢你的帮助。
最佳答案
使用一些乐趣 rlang
东西 & purrr
:
library(rlang)
library(purrr)
library(dplyr)
df <- data.frame(alpha.num = c(1, 3, 5, 7),
alpha.char = c("a", "c", "e", "g"),
beta.num = c(2, 4, 6, 8),
beta.char = c("b", "d", "f", "h"),
which.to.use = c("alpha", "alpha", "beta", "beta"),
stringsAsFactors = F)
c("num", "char") %>%
map(~ mutate(df, !!sym(paste0("chosen.", .x)) :=
case_when(
which.to.use == "alpha" ~ !!sym(paste0("alpha.", .x)),
which.to.use == "beta" ~ !!sym(paste0("beta.", .x))
))) %>%
reduce(full_join)
结果:
alpha.num alpha.char beta.num beta.char which.to.use chosen.num chosen.char
1 1 a 2 b alpha 1 a
2 3 c 4 d alpha 3 c
3 5 e 6 f beta 6 f
4 7 g 8 h beta 8 h
无
reduce(full_join)
:c("num", "char") %>%
map_dfc(~ mutate(df, !!sym(paste0("chosen.", .x)) :=
case_when(
which.to.use == "alpha" ~ !!sym(paste0("alpha.", .x)),
which.to.use == "beta" ~ !!sym(paste0("beta.", .x))
))) %>%
select(-ends_with("1"))
alpha.num alpha.char beta.num beta.char which.to.use chosen.num chosen.char
1 1 a 2 b alpha 1 a
2 3 c 4 d alpha 3 c
3 5 e 6 f beta 6 f
4 7 g 8 h beta 8 h
解释:
(注意:我没有完全或什至没有得到
rlang
。也许其他人可以给出更好的解释;)。使用
paste0
当我们需要 mutate
的裸名时,它本身会产生一个字符串。知道它指的是一个变量名。如果我们包装
paste0
在 sym
,它的计算结果是一个裸名:> x <- varrnames[1]
> sym(paste0("alpha.", x))
alpha.num
但是
mutate
不知道评估,而是将其视为符号:> typeof(sym(paste0("alpha.", x)))
[1] "symbol"
“砰砰”声
!!
运算符计算 sym
功能。相比:> expr(mutate(df, var = sym(paste0("alpha.", x))))
mutate(df, var = sym(paste0("alpha.", x)))
> expr(mutate(df, var = !!sym(paste0("alpha.", x))))
mutate(df, var = alpha.num)
所以与
!!sym
我们可以使用 paste 来动态调用带有 dplyr 的变量名。
关于r - dplyr 使用 case_when 改变新的动态变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51644516/