在R的dplyr中,为何相同值的行用==匹配时部分不生效?
问题原因与解决方案
一、代码逻辑错误(核心问题)
你当前代码里的medium_code == pressAbo写法存在逻辑错误:==是逐元素相等比较,当medium_code是单个值、pressAbo是向量时,R会自动循环向量元素进行匹配,这会导致部分行匹配混乱,出现无意义的NA。正确的写法应该用%in%,用来判断单个值是否存在于目标向量中。
二、肉眼不可见字符的排查方法
如果修正%in%后仍有部分行匹配失败,再排查字符的隐形差异,可按以下步骤操作:
- 检查字符串长度:对疑似有问题的
medium_code值,用nchar()查看长度,比如显示为"NZZ"的行,正常长度是3,若有隐藏空格则长度为4。query %>% filter(medium_code == "NZZ") %>% mutate(len = nchar(medium_code)) - 去除前后空格:先清理
medium_code的首尾空白字符,再进行匹配:query <- query %>% mutate(medium_code = trimws(medium_code)) - 查看原始字符编码:用
charToRaw()查看字符的十六进制编码,对比正常和异常值的差异:# 取正常的NZZ和异常的NZZ分别查看 charToRaw(query$medium_code[which(query$medium_code == "NZZ")[1]]) charToRaw(query$medium_code[which(is.na(query$Gattung) & query$medium_code == "NZZ")[1]]) - 统一大小写:如果存在大小写不一致(比如"nzz"和"NZZ"),统一转换为大写或小写后再匹配:
query <- query %>% mutate(medium_code = toupper(medium_code))
三、修正后的完整代码
library(dplyr) pressAbo <- c("NZZ", "BU", "TA", "NLZ", "BZ", "BAZ", "AZM", "SGT") pressBLV <- c("BLI") pressSM <- c("SBLI", "TAS", "WOZ", "NZZS", "SAS") pressPen <- c("ZWA") onlineAbo <- c("NZZO", "NNTA", "NNBE", "NNBS", "SGTO", "LUZO") onlineBLV <- c("BLIO") onlinePen <- c("ZAWO") # 先清理medium_code的潜在问题 query <- query %>% mutate(medium_code = trimws(toupper(medium_code))) %>% mutate(Gattung = case_when( medium_code %in% c(pressAbo, pressBLV, pressSM, pressPen) ~ "Presse", medium_code %in% c(onlineAbo, onlineBLV, onlinePen) ~ "Online", # 可添加默认值,避免NA TRUE ~ "Unknown" ), .after="medium_name")
内容的提问来源于stack exchange,提问作者Valpal
相关产品推荐
相关产品推荐

