如何在tidyverse中基于type变量动态判断tx列生成valid列
问题说明
现有包含id、type及多个tx_*列的数据框,需新增valid列,规则如下:
- 当
type == "inf"且任意tx_*列值为"yes"时,valid = 1 - 当
type == "nif"且存在任意两个连续的tx_*列值为"yes"时,valid = 1 - 其余情况
valid = 0
用户尝试在case_when中直接使用contains()这类tidyselect函数匹配tx列,但无法生效,希望找到不用指定具体tx列的方案(后续可能新增tx列)。
示例代码
library(tidyverse) id <-c(1:5) type <- c("inf", "nif","nif","inf","inf") tx_1 <-c("no", "no", "no","no", "yes") tx_2 <- c("yes", "no", "no","yes", "no") tx_3 <- c("no", "yes", "no","no", "no") tx_4 <- c("yes", "yes", "no","yes", "no") tx_5 <- c("no", "no", "no","yes", "no") df <- data.frame(id,type,tx_1,tx_2,tx_3,tx_4,tx_5)
解决方案
用rowwise()按行分组,搭配c_across()引用所有tx列,再结合case_when就能实现需求,代码如下:
df <- df |> rowwise() |> mutate( # 把所有tx列的yes/no转成逻辑向量,存为临时列表列 tx_logic = list(c_across(contains("tx")) == "yes"), valid = case_when( # inf类型:只要有一个tx是yes就设为1 type == "inf" & any(tx_logic) ~ 1, # nif类型:检查是否有连续两个yes type == "nif" & any(tx_logic[-1] & tx_logic[-length(tx_logic)]) ~ 1, # 其他情况都设为0 TRUE ~ 0 ) ) |> ungroup() |> select(-tx_logic) # 删掉临时列
关键逻辑解释
rowwise():让后续操作逐行执行,这样才能对每一行的tx列单独判断c_across(contains("tx")):自动匹配所有含"tx"的列,不用手动列出来,新增tx列也能自动识别tx_logic[-1] & tx_logic[-length(tx_logic)]:把逻辑向量错位后做与运算,只要有一个结果为TRUE,就说明存在连续两个"yes"ungroup():处理完后取消行分组,避免影响后续操作
内容的提问来源于stack exchange,提问作者a nony mouse
相关产品推荐
相关产品推荐

