使用dplyr多条件if-else构建Issues标记列的问题求助
问题分析与解决方案
原代码的核心问题
ifelse返回值逻辑错误:后续mutate中用c(Issues, "County")拼接向量,不符合ifelse的要求——ifelse需要返回与输入长度完全一致的向量,这种拼接会导致长度不匹配,最终结果混乱。- 日期初始化错误:
as.Date(2024-02-15)会先计算数值2024-2-15=2007,再转成1970-01-01加2007天的日期,这完全不是预期的2024-02-15,应写成as.Date("2024-02-15")。
解决方案1:逐步拼接问题字符串(基础版)
用dplyr结合stringr::str_c,每次满足条件时将新问题追加到已有Issues字符串后,用分隔符区分多个问题:
library(dplyr) library(stringr) # 修正初始数据的Date列 df <- data.frame( PreferredName = "", FirstName = c("Mary", "Harold (Harry)", "Ben", "Tristian (Tri)", "Julia"), County = c("", "Other", "Warren", "Butler", ""), Date = as.Date("2024-02-15"), # 修正引号 Address = c("123 Street", "42 Ave", "", "", "520 Road") ) df_cor <- df %>% # 初始化Issues列 mutate(Issues = ifelse(PreferredName == "" & grepl("\\(", FirstName), "Preferred Name", "")) %>% # 追加County问题 mutate(Issues = ifelse((County %in% c("USA", "", "Other", "N/A")) & Date >= as.Date("2023-08-01"), str_c(Issues, "County", sep = ", "), Issues)) %>% # 追加Address问题 mutate(Issues = ifelse(Address == "" & Date >= as.Date("2023-08-01"), str_c(Issues, "Address", sep = ", "), Issues)) %>% # 去掉开头的多余分隔符(如果初始为空的话) mutate(Issues = str_remove(Issues, "^, "))
解决方案2:生成问题列表再合并(更清晰)
如果条件较多,推荐先为每个问题生成标记,再将所有符合条件的问题合并成字符串,可读性更强:
library(dplyr) library(stringr) library(purrr) df_cor <- df %>% mutate( # 为每个问题生成单独的标记 pref_name_issue = ifelse(PreferredName == "" & grepl("\\(", FirstName), "Preferred Name", NA), county_issue = ifelse((County %in% c("USA", "", "Other", "N/A")) & Date >= as.Date("2023-08-01"), "County", NA), address_issue = ifelse(Address == "" & Date >= as.Date("2023-08-01"), "Address", NA), # 合并所有非NA的问题 Issues = pmap_chr(list(pref_name_issue, county_issue, address_issue), ~ str_c(na.omit(c(...)), collapse = ", ")) ) %>% # 移除临时列(可选) select(-pref_name_issue, -county_issue, -address_issue)
说明
- 用
%in%替代多个|,让条件判断更简洁。 pmap_chr来自purrr包,可按行处理多个列的内容,na.omit会自动过滤不符合条件的空值。- 如果需要空字符串而非
NA,可在最后加mutate(Issues = ifelse(Issues == "", "", Issues))调整逻辑。
内容的提问来源于stack exchange,提问作者ayw36
相关产品推荐
相关产品推荐

