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

在R中基于动物ID与采样日期清理特定Initials列NA行

解决方案:按动物-采样日期分组清理Initials列的NA行

需求梳理

针对每一组AnimalID + DateSampled:

  • 当组内存在2个非NA值+2个NA值时,删除所有NA行
  • 当组内全为NA值时,保留所有行
  • 当组内存在**4个非NA值(两组采样人员各2行)**时,保留所有行

实现方案

方法1:使用dplyr(推荐,简洁高效)

利用分组计算组内非NA的数量,再根据条件筛选行:

library(dplyr)

# 初始化示例数据(修正原数据的长度匹配问题)
Data <- data.frame(matrix(ncol = 3, nrow = 24))
colnames(Data) <- c('AnimalID', 'DateSampled', 'Initials')

Data$AnimalID <- c(1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6)
Data$DateSampled <- as.Date(c("2021-10-13", "2021-10-13", "2021-10-13", "2021-10-13", 
                              "2021-10-27", "2021-10-27", "2021-10-27", "2021-10-27", 
                              "2021-11-10", "2021-11-10", "2021-11-10", "2021-11-10", 
                              "2021-11-24", "2021-11-24", "2021-11-24", "2021-11-24", 
                              "2021-12-01", "2021-12-01", "2021-12-01", "2021-12-01", 
                              "2021-12-05", "2021-12-05", "2021-12-05", "2021-12-05"))
Data$Initials <- c("AB", "AB", NA, NA, "AB", "AB", "CD", "CD", "AB", "AB", NA, NA, 
                   "AB", "AB", "CD", "CD", "AB", "AB", NA, NA, NA, NA, NA, NA)

# 核心处理逻辑
cleaned_data <- Data %>%
  group_by(AnimalID, DateSampled) %>%
  mutate(
    non_na_count = sum(!is.na(Initials)),
    all_na = all(is.na(Initials))
  ) %>%
  filter(
    # 保留非NA行,或者全为NA时的所有行
    !is.na(Initials) | all_na
  ) %>%
  select(-non_na_count, -all_na) %>% # 移除临时计算列
  ungroup()

# 查看结果
print(cleaned_data, n = Inf)

方法2:基础R实现(循环+条件向量)

如果不想依赖tidyverse包,用基础R分组循环处理:

# 初始化示例数据(同上)
# ... 此处省略数据初始化代码,与上面一致 ...

# 生成分组标识键
group_keys <- paste(Data$AnimalID, Data$DateSampled, sep = "_")
unique_groups <- unique(group_keys)

# 初始化行保留标记向量
keep_rows <- logical(nrow(Data))

# 遍历每个分组处理
for(g in unique_groups){
  group_rows <- which(group_keys == g)
  group_initials <- Data$Initials[group_rows]
  non_na_count <- sum(!is.na(group_initials))
  
  if(non_na_count == 2){
    # 组内有2个非NA,仅保留非NA行
    keep_rows[group_rows] <- !is.na(group_initials)
  } else if(non_na_count == 0){
    # 组内全为NA,保留所有行
    keep_rows[group_rows] <- TRUE
  } else {
    # 其他情况(如4个非NA),保留所有行
    keep_rows[group_rows] <- TRUE
  }
}

# 筛选得到清理后的数据
cleaned_data_base <- Data[keep_rows, ]

# 查看结果
print(cleaned_data_base, n = Inf)

输出结果

两种方法都会生成符合需求的输出:

# A tibble: 18 × 3
   AnimalID DateSampled Initials
      <dbl> <date>      <chr>   
 1        1 2021-10-13  AB      
 2        1 2021-10-13  AB      
 3        2 2021-10-27  AB      
 4        2 2021-10-27  AB      
 5        2 2021-10-27  CD      
 6        2 2021-10-27  CD      
 7        3 2021-11-10  AB      
 8        3 2021-11-10  AB      
 9        4 2021-11-24  AB      
10        4 2021-11-24  AB      
11        4 2021-11-24  CD      
12        4 2021-11-24  CD      
13        5 2021-12-01  AB      
14        5 2021-12-01  AB      
15        6 2021-12-05  NA      
16        6 2021-12-05  NA      
17        6 2021-12-05  NA      
18        6 2021-12-05  NA      

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 11:50:44