想要使用 dplyr 和case_when
将一系列指标列折叠为单个列。挑战是我希望能够折叠未指定/动态数量的列。
考虑以下数据集,gear
已被分成一系列指标列。
library(dplyr)
data(mtcars)
mtcars = mtcars %>%
mutate(g2 = ifelse(gear == 2, 1, 0),
g3 = ifelse(gear == 3, 1, 0),
g4 = ifelse(gear == 4, 1, 0)) %>%
select(g2, g3, g4)
我正在尝试编写一个执行相反操作的函数。
当我知道有多少情况可以这样做时,如下所示:
combine_indices = function(db, cols, vals){
db %>% mutate(new_col = case_when(!!sym(cols[1]) == 1 ~ vals[1],
!!sym(cols[2]) == 1 ~ vals[2],
!!sym(cols[3]) == 1 ~ vals[3]))
}
cols = c("g2", "g3", "g4")
vals = c(2,3,4)
combine_indices(mtcars, cols, vals)
不过,我想要combine_indices
函数来处理任意数量的索引列(现在它只适用于三个)。
根据文档(?case_when
),“如果您的模式存储在列表中,您可以将其拼接为!!!
“。但我无法让这个工作:
patterns = list(sym(cols[1] == 1 ~ vals[1],
sym(cols[2] == 1 ~ vals[2],
sym(cols[3] == 1 ~ vals[3])
mtcars %>% mutate(new_col = case_when(!!!patterns))
只产生一个充满 NA 的新列。
If !!!patterns
成功了,那么获取列表就很简单了cols
and vals
并生成patterns
。但是,我无法得到正确的报价。希望更熟悉quosures的人知道如何做。
注意-这里的一些类似问题是使用连接或其他函数解决的。但是,我仅限于使用case_when
因为使用 dbplyr 时它如何转换为 sql。