You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于列计数筛选行并按另一列分组(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)
代码说明
  1. 数据清洗:原数据中NA以字符串形式存在,先转换为R原生NA,避免后续统计错误;
  2. 确定有效物种:过滤掉NA行后统计每个物种的出现次数,提取出次数≥3的物种列表;
  3. 筛选站点:按code分组,只要该组内存在至少一个有效物种,就保留整个组的所有行(包括NA行);
  4. 取消分组:最终得到符合要求的数据集。

运行代码后输出结果与期望一致。

内容的提问来源于stack exchange,提问作者pmp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 11:07:05