使用!str_detect过滤数据框时行数异常及城市列清洗求助
问题原因分析
这个问题我在做数据清洗时也碰到过,核心根源是**str_detect()处理缺失值(NA)的逻辑**容易被忽略:
- 当
city列的值是NA或者空字符串""时,str_detect(city, '\u00B0')会返回NA,而不是我们直觉里的FALSE dplyr::filter()的规则是:任何返回NA的行都会被自动剔除,不会保留在结果集中- 你用
df.degree筛选出了30个确实带度数符号的行,但!str_detect(...)的筛选逻辑会同时过滤掉两类行:- 那30个带度数符号的行(
str_detect返回TRUE,取反后为FALSE,被过滤) - 所有
city为NA或空字符串的行(str_detect返回NA,取反后仍是NA,被过滤)
这就导致最终df.withoutdegree的行数远少于预期的4970。
- 那30个带度数符号的行(
解决方法
我们需要明确把缺失值/空字符串的情况纳入保留范围,这里有两种简洁的实现方式:
方法一:直接补充缺失值保留条件
在filter里明确指定,保留city是NA、空字符串,或者不包含度数符号的行:
df.withoutdegree <- df %>% filter(is.na(city) | city == "" | !str_detect(city, '\u00B0'))
方法二:利用str_detect的negate参数(更优雅)
str_detect本身提供了negate参数,可以直接反转匹配结果,再结合缺失值判断:
df.withoutdegree <- df %>% filter(is.na(city) | city == "" | str_detect(city, '\u00B0', negate = TRUE))
验证思路
你可以先统计一下city列中NA和空字符串的行数,来验证这个问题:
df %>% summarise( na_city = sum(is.na(city)), empty_city = sum(city == "", na.rm = TRUE), total_missing = na_city + empty_city )
把这个total_missing的数值加上4970,应该刚好等于原数据的5000行,这就能实锤是缺失值导致的异常了。
内容的提问来源于stack exchange,提问作者Danilo Saft
相关产品推荐
相关产品推荐

