R语言函数内删除数据框因子水平及过滤无效数据问题求解
完整修改后代码
split_frames<- function(OG_DF, factorVAR1, factorVAR2, VAR, frame_name){ # 按factorVAR1拆分原始数据框 splitted <- split(OG_DF, as.factor(OG_DF[,factorVAR1])) new_names <- paste0(levels(as.factor(OG_DF[,factorVAR1])), frame_name) for (i in seq_along(splitted)) { # 移除度量变量VAR为NA的行 splitted[[i]] <- splitted[[i]][!is.na(splitted[[i]][,VAR]), ] # 统计当前子框中factorVAR2各水平的观测数 fct_count <- table(droplevels(as.factor(splitted[[i]][,factorVAR2]))) # 筛选出观测数>3的水平,作为要保留的水平 fct_keep <- names(fct_count)[fct_count > 3] # 没有符合保留条件的水平,直接标记为无效 if (length(fct_keep) == 0) { splitted[[i]] <- NA } else { # 仅保留指定水平的行,清理冗余因子 splitted[[i]] <- droplevels(splitted[[i]][splitted[[i]][,factorVAR2] %in% fct_keep, ]) # 统计剩余的factorVAR2水平数 N_levels <- nlevels(as.factor(splitted[[i]][,factorVAR2])) # 剩余水平不足2个,标记为无效 if (N_levels < 2) { warning("The data frame ", new_names[i], " is excluded from further analysis \n because it does not contain all factor levels needed.\n") splitted[[i]] <- NA } else { # 符合条件的写入全局环境 assign(new_names[i], splitted[[i]], envir = .GlobalEnv) message("Analysis ready for: ", new_names[i]) } } } # 过滤掉列表中无效的NA项,返回有效数据框列表 splitted <- Filter(Negate(is.na), splitted) return(invisible(splitted)) }
核心修改说明
- 修复无符合条件水平时的异常:新增
length(fct_keep) == 0的前置判断,避免空向量匹配导致全部行被误删的问题 - 修正筛选逻辑:弃用易出问题的
-which()写法,直接用%in%匹配保留水平,规避空返回时删除全部行的bug - 修正水平数统计逻辑:原代码错误统计了拆分依据
factorVAR1的水平数(拆分后每个子框的factorVAR1天然只有1个水平,会导致所有子框都被误判为无效),改为统计factorVAR2的剩余水平数 - 优化冗余水平清理:统一在筛选完成后调用
droplevels(),避免重复调用导致的逻辑混乱 - 新增返回值:函数最后会返回过滤后的有效数据框列表,方便后续链式调用
内容的提问来源于stack exchange,提问作者Nadiine El Nino
相关产品推荐
相关产品推荐

