r - dplyr case_when 具有动态案例数

标签 r dplyr quosure

想使用 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 的新列。

!!!patterns工作,那么采用列表 cols 就很简单了。和 vals并生成 patterns .但是,我无法获得正确的 quosures。希望更熟悉quosures的人知道如何。

注意 - 这里的一些类似问题是使用连接或其他函数解决的。 但是,我只能使用 case_when 因为它在使用 dbplyr 时如何转换为 sql。

最佳答案

我们可以创建一串条件,使用 parse_exprs并将其拼接( !!! )。

library(dplyr)
library(rlang)

combine_indices = function(db, cols, vals){
   db %>% mutate(new_col = case_when(!!!parse_exprs(paste(cols, '== 1 ~', vals))))
}


cols = c("g2", "g3", "g4")
vals = c(2,3,4)
combine_indices(mtcars, cols, vals)

返回:
#   g2 g3 g4 new_col
#1   0  0  1       4
#2   0  0  1       4
#3   0  0  1       4
#4   0  1  0       3
#5   0  1  0       3
#6   0  1  0       3
#....

哪里pastecase_when 生成条件动态。
paste(cols, '== 1 ~', vals)
#[1] "g2 == 1 ~ 2" "g3 == 1 ~ 3" "g4 == 1 ~ 4"

关于r - dplyr case_when 具有动态案例数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61789717/

相关文章:

r - 如何设置一个独立的进度条

r - 如何摆脱 R 字符串的重复逗号

r - 计算给定开始日期和结束日期之间每个季度的平均价格?

r - 根据与 data.frame 的相似性对字符串进行分组

r - dplyr .data 代词与 "quosure"方法

r - 在 data.table 列中使用列表

r - dplyr:group_by 和汇总以折叠(通过串联)包含 NA 的字符串列

R:对数据帧的子集快速执行操作,然后在没有内部函数的情况下重新聚合结果

r - 使用 dplyr 将列名作为参数传递给函数

r - 在不同变量上运行 lm 的函数