r - dplyr case_when 具有动态案例数
问题描述
想要使用 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的人知道如何。
注意 - 这里的一些类似的问题是使用连接或其他功能解决的。但是,由于在使用 dbplyr 时它如何转换为 sql ,我只能使用它。case_when
解决方案
我们可以创建一串条件,使用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
#....
where动态paste
生成条件case_when
。
paste(cols, '== 1 ~', vals)
#[1] "g2 == 1 ~ 2" "g3 == 1 ~ 3" "g4 == 1 ~ 4"
推荐阅读
- selenium - Java-Selenium 没有支持包
- php - 如何在 Laravel 中将时间(01:10:00)转换为 1h 10m 短代码
- python-3.x - Django将模型从一个应用程序移动到另一个应用程序-ValueError:该字段是用惰性引用声明的,但应用程序不提供模型
- redis - 当我尝试链接调用时,反应式 redis 挂起
- android - 如何在房间数据库中保存外键
- python - 合并具有已知位置的两个点云(python,OpenCV) - 转换
- javascript - 用户滚动到第二篇文章后,Google 跟踪代码管理器未触发 percent_scrolled=90,我使用了无限滚动
- node.js - 在 Ubuntu 18 上安装 nvm 和更新 nodejs 的问题
- linux - 如何在 AWK 中将字段分隔符设置为 ^@(特殊字符)?
- excel - 比较不同的 Excel 排列