使用base R/dplyr过滤分类变量后水平未消失的问题排查
分类变量筛选后水平未自动删除的原因与解决办法
核心原因
R里的**分类变量(factor)**设计上会保留变量的所有原始水平,不管这些水平在筛选后的数据集里有没有对应的数据行。dplyr::filter()只负责筛选符合条件的行,不会主动修改分类变量的水平集合,所以你筛选后查levels还是和原来一致,这是正常现象。
实用解决办法
直接删除空水平
这是你已经用到的方法,直接对筛选后的分类变量用droplevels()就行,也可以对整个数据集操作:# 单独处理某个变量 df_clean$City <- droplevels(df_clean$City) df_clean$Risk <- droplevels(df_clean$Risk) # 一次性处理整个数据集的所有分类变量 df_clean <- droplevels(df_clean)整合到dplyr管道流程
把droplevels()加到筛选后的步骤里,一步完成:df_clean <- df_clean %>% filter(City %in% c("Chicago","312CHICAGO", "CCHICAGO", "CHCHICAGO", "CHCICAGO","chicago", "Chicago", "CHicago", "CHICAGO", "CHICAGOC","CHICAGOCHICAGO", "CHICAGOI", "CHICAGOO", "312CHICAGO")) %>% droplevels()先转字符型再筛选(按需选择)
如果不需要保留分类变量类型,或者想直接得到只有实际存在值的水平,可以先转成字符型筛选,之后再转回factor:df_clean <- df_clean %>% mutate(City = as.character(City)) %>% filter(City %in% c("Chicago","312CHICAGO", "CCHICAGO", ...)) %>% mutate(City = as.factor(City))全局设置(谨慎使用)
可以设置全局选项让dplyr自动删除空水平,但这个设置会影响所有dplyr筛选操作,可能带来意外后果:options(dplyr.drop_levels = TRUE)
内容的提问来源于stack exchange,提问作者AirIcarus
相关产品推荐
相关产品推荐

