R语言:按分组删除Var2/Var3中出现次数最少的行
解决方案:按分组筛选非0值次数较多的列对应的行
针对你处理大规模数据集的需求,我整理了一套高效的解决方案,核心思路是按Var1分组后,先统计每组内Var2和Var3非0值的出现次数,再根据次数筛选保留符合要求的行:
1. 加载依赖包并构建数据集
首先我们用dplyr包(处理分组数据效率极高,适合大规模数据集),先构建你的示例数据集:
library(dplyr) # 构建示例数据集(修正类型问题,避免自动转因子) Var1 = c("Rank 1", "Rank 1", "Rank 2", "Rank 1", "Rank 2") Var2 = c("Sub 1", "Sub 1", "Sub 2","0", "Sub 2") Var3 = c(0, "Sub 1", 0, "Sub 1", "0" ) Var4 = c(10,20, 30, 40,50) df <- data.frame(Var1, Var2, Var3, Var4, stringsAsFactors = FALSE)
2. 数据预处理与分组筛选
接下来统一处理Var2和Var3的类型,然后按Var1分组统计、筛选:
# 统一将0转为字符"0",确保类型一致(避免混合数字/字符导致统计错误) df <- df %>% mutate(across(c(Var2, Var3), ~ as.character(.x))) %>% mutate(across(c(Var2, Var3), ~ ifelse(.x == "0", "0", .x))) # 按Var1分组处理,筛选符合要求的行 result_df <- df %>% group_by(Var1) %>% mutate( # 统计每组内Var2非0的次数 count_var2 = sum(Var2 != "0"), # 统计每组内Var3非0的次数 count_var3 = sum(Var3 != "0") ) %>% # 核心筛选逻辑:保留次数多的列对应的非0行;若次数相等,默认保留Var2的非0行(可按需调整) filter( (Var2 != "0" & count_var2 >= count_var3) | (Var3 != "0" & count_var3 > count_var2) ) %>% # 移除临时统计列 select(-count_var2, -count_var3) %>% ungroup() # 查看最终结果 print(result_df)
3. 结果说明
运行上述代码后,得到的结果和你期望的一致:
# A tibble: 4 × 4 Var1 Var2 Var3 Var4 <chr> <chr> <chr> <dbl> 1 Rank 1 Sub 1 0 10 2 Rank 1 Sub 1 Sub 1 20 3 Rank 2 Sub 2 0 30 4 Rank 2 Sub 2 0 50
代码逻辑解释
- 类型统一:把
Var2和Var3里的数字0转为字符"0",避免因为类型混合导致统计错误; - 分组统计:按
Var1分组后,计算每组内Var2和Var3非0值的出现次数; - 筛选规则:如果
Var2的非0次数更多或相等,保留Var2非0的行;如果Var3的非0次数更多,保留Var3非0的行,自动删除次数少的列中存在非0值的行; - 高效处理:
dplyr的分组操作是向量式运算,处理大规模数据集时速度远快于循环,非常适合你的场景。
内容的提问来源于stack exchange,提问作者Maylo
相关产品推荐
相关产品推荐

