如何基于列计数筛选行并按另一列分组(R语言)
问题描述
我有一个包含多列的data frame,需求如下:
- 筛选仅包含特定属物种的行(
spp列记录目标物种名称,非目标物种标记为NA),且该物种在全数据集中出现次数至少为3次; - 同时按
code列分组,排除仅包含出现次数不足3次物种的code站点。
现有数据及尝试代码如下:
df <- data.frame( spp = c("sp1", "sp1", "sp1","NA", "NA", "sp3", "sp3", "sp3", "sp3", "NA", "NA", "NA", "NA", "NA"), code = c("a", "b", "c","a", "e", "d", "a", "b", "c", "f", "b","a","b","c"), va1 = c(1, 2, 2, 2,4, 3, 3, 4, 5, 5, 5,6,7,8) ) filtered_df <- df %>% group_by(code) %>% filter(n() >= 3)
尝试设置不统计NA但未成功,期望输出仅保留符合条件的物种及code站点(如code为e、f的站点因无满足次数要求的物种需被排除),示例输出如下:
spp code va1 1 sp1 a 1 2 sp1 b 2 3 sp1 c 2 4 NA a 2 5 sp3 d 4 6 sp3 a 3 7 sp3 b 3 8 sp3 c 3 9 NA b 4 10 NA a 5 11 NA b 6 12 NA c 7
解决方案
分两步完成筛选:先确定有效物种,再筛选包含有效物种的站点,具体代码如下:
library(dplyr) # 将字符串"NA"转换为R原生NA值,避免统计误差 df_cleaned <- df %>% mutate(spp = ifelse(spp == "NA", NA, spp)) # 提取全数据集中出现次数≥3次的物种 valid_spp <- df_cleaned %>% filter(!is.na(spp)) %>% count(spp) %>% filter(n >= 3) %>% pull(spp) # 筛选包含有效物种的code站点,保留站点内所有行(包括NA) filtered_df <- df_cleaned %>% group_by(code) %>% filter(any(spp %in% valid_spp)) %>% ungroup() # 查看结果 print(filtered_df)
代码说明
- 数据清洗:原数据中
NA以字符串形式存在,先转换为R原生NA,避免后续统计错误; - 确定有效物种:过滤掉
NA行后统计每个物种的出现次数,提取出次数≥3的物种列表; - 筛选站点:按
code分组,只要该组内存在至少一个有效物种,就保留整个组的所有行(包括NA行); - 取消分组:最终得到符合要求的数据集。
运行代码后输出结果与期望一致。
内容的提问来源于stack exchange,提问作者pmp
相关产品推荐
相关产品推荐

