如何用dplyr的case_when根据变量名列判断对应值是否非空?
解决方法
报错原因
get()函数仅能处理单个字符串对象,无法直接接收长度大于1的向量(即整个last_question列),而case_when是向量化操作,直接传入整列会触发参数长度不匹配的错误。
方案1:使用rowwise()逐行处理(dplyr风格)
通过rowwise()让代码逐行执行,此时每行的last_question是单个字符串,get()可以正确获取对应列的取值:
library(dplyr) # 修正原始数据以匹配预期输出 id <- c(1, 2, 3, 4, 5) q1 <- c('Australia', 'Italy', 'Peru', 'China', 'Vermont') q2 <-c('d', NA, 'y', NA, 'we') q3 <- c(NA, 'm', NA, 'wsp', 'op') q4 <- c(NA, NA, NA, NA, 29) last_question <-c("q1","q4","q2","q3","q4") test <- data.frame(id, q1, q2, q3, q4, last_question) # 生成completion列 test <- test %>% rowwise() %>% mutate(completion = case_when( !is.na(get(last_question)) ~ "yes", TRUE ~ "no" )) %>% ungroup() # 取消行分组,避免影响后续操作 print(test)
方案2:使用矩阵索引(高效,适合大数据集)
借助base R的矩阵索引,直接提取每行对应last_question列的取值,无需逐行分组:
# 修正后的原始数据同上 id <- c(1, 2, 3, 4, 5) q1 <- c('Australia', 'Italy', 'Peru', 'China', 'Vermont') q2 <-c('d', NA, 'y', NA, 'we') q3 <- c(NA, 'm', NA, 'wsp', 'op') q4 <- c(NA, NA, NA, NA, 29) last_question <-c("q1","q4","q2","q3","q4") test <- data.frame(id, q1, q2, q3, q4, last_question) # 获取每个last_question对应的列索引 col_indices <- match(test$last_question, colnames(test)) # 提取每行对应位置的数值 last_values <- test[cbind(1:nrow(test), col_indices)] # 生成completion列 test$completion <- ifelse(!is.na(last_values), "yes", "no") print(test)
预期输出
id q1 q2 q3 q4 last_question completion 1 1 Australia d <NA> NA q1 yes 2 2 Italy <NA> m NA q4 no 3 3 Peru y <NA> NA q2 yes 4 4 China <NA> wsp NA q3 yes 5 5 Vermont we op 29 q4 yes
内容的提问来源于stack exchange,提问作者Catherine
相关产品推荐
相关产品推荐

