如何检查数据框多列中值是否落在排除特定值的范围内
检查数据框多列值是否在指定范围并排除特定标记值
看起来你需要排查数据框里Text1到Text4这些列的值是否落在指定范围内,同时排除像800这样的特定标记值,对吧?我给你两种实用的实现方案,不管你习惯基础R还是tidyverse语法都能用上:
首先先把你的数据集复现出来,方便后续操作:
# 构建你的数据集 data <- structure(list( ID = 1:10, Text1 = c(5L, 8L, 3L, 1L, 3L, 67L, 800L, 5L, 9L, 2L), Text2 = c(800L, 800L, 2L, NA, 14L, 3L, 70L, 6L, 9L, 1L), Text3 = c(3L, 88L, 800L, NA, 4L, NA, 7L, 5L, 7L, 800L), Text4 = c(1L, 6L, 12L, 1L, 6L, 800L, 1L, NA, 8L, 2L) ), .Names = c("ID", "Text1", "Text2", "Text3", "Text4"), class = "data.frame", row.names = c(NA, -10L))
先定义核心参数
先把需要的参数明确下来,方便你后续修改:
cols_to_check:要检查的目标列(这里是Text1到Text4)min_val/max_val:你指定的数值范围(我暂时设为1-100,你可以按需调整)exclude_val:需要排除的特定标记值(这里是800)
cols_to_check <- c("Text1", "Text2", "Text3", "Text4") min_val <- 1 max_val <- 100 exclude_val <- 800
方案1:基础R实现,无需额外包
如果你不想加载第三方包,用基础R就能完成:
第一步:标记每个单元格的问题情况
我们可以循环检查每一列,生成一个结果框,标记哪些单元格不符合要求(要么是800,要么超出范围,要么是NA):
# 创建结果数据框,先放ID列 check_result <- data.frame(ID = data$ID) # 逐列检查并标记 for(col in cols_to_check) { # 条件:不符合范围 或 等于标记值 或 是NA(如果不需要把NA算问题,就去掉is.na(.x)) check_result[[paste0(col, "_check")]] <- !((data[[col]] >= min_val & data[[col]] <= max_val) & data[[col]] != exclude_val) } # 查看标记结果 check_result
输出里TRUE代表该单元格有问题,FALSE是符合要求的。
第二步:筛选出有问题的行
如果想直接找出至少有一个列不符合要求的记录,可以这样:
# 筛选出存在问题的行 problem_rows <- data[rowSums(check_result[, -1], na.rm = TRUE) > 0, ] problem_rows
方案2:tidyverse(dplyr)实现,代码更简洁
如果你平时用tidyverse的话,代码会更直观:
方式1:标记每行是否存在问题
library(dplyr) data %>% rowwise() %>% mutate( # 检查当前行是否有任意一列不符合要求 has_problem = any( across(all_of(cols_to_check), ~ .x == exclude_val | .x < min_val | .x > max_val | is.na(.x)), na.rm = TRUE ) ) %>% ungroup() %>% # 可选:只保留有问题的行 filter(has_problem)
方式2:细致标记每一列的问题
如果想看到每一列的具体问题情况,可以这样:
data %>% mutate( across(all_of(cols_to_check), ~ .x == exclude_val | .x < min_val | .x > max_val | is.na(.x), .names = "{col}_problem") )
小提示
- 如果你不把NA视为问题,只需要把所有条件里的
is.na(.x)删掉就行 - 如果是要保留符合要求的行,只需要把条件反过来(比如在dplyr里用
filter(!has_problem)) - 所有参数都可以根据你的实际需求修改,比如范围改成0-50,标记值改成其他数字
内容的提问来源于stack exchange,提问作者rohuhodoso
相关产品推荐
相关产品推荐

