基于多条件的唯一值累积求和及物种观测统计问题
解决方案
首先构造贴近实际场景的测试数据(包含同一物种-站点-年份的多条记录):
set.seed(123) df <- data.frame( Country = rep(LETTERS[1:2], each = 10), Site = rep(c("F", "G"), each = 5, times = 2), species = rep(c(1, 2), each = 5, times = 2), Year = sample(1981:1983, 20, replace = TRUE) )
核心代码实现
使用dplyr完成累积计算,同时保留所有原始列:
library(dplyr) df_processed <- df %>% # 过滤1980年之后的记录 filter(Year > 1980) %>% # 按「国家-站点-物种」分组,确保同一物种在同一站点的所有记录归为一组 group_by(Country, Site, species) %>% # 按年份排序,保证累积计算的时间顺序正确 arrange(Year, .by_group = TRUE) %>% # 计算累积记录数Spsum:分组内的行号即为到当前行的总记录数 mutate(Spsum = row_number()) %>% # 计算累积不同年份数nYear:标记首次出现的年份后累积求和 mutate( is_new_year = !duplicated(Year), nYear = cumsum(is_new_year) ) %>% # 移除中间辅助列(可选) select(-is_new_year) %>% ungroup()
代码说明
- 分组逻辑:必须按
Country, Site, species分组,才能在同一物种-站点的范围内计算累积值,避免跨组干扰。 - 排序:按
Year排序是累积计算的前提,确保统计是按时间顺序逐步累加。 - Spsum计算:
row_number()在分组内从1开始递增,正好对应到当前行的累积记录总数,完全匹配你示例中「1981年5次、1982年2次,Spsum最终为7」的需求。 - nYear计算:
!duplicated(Year)标记当前年份是否是该分组内的首次出现(首次出现为TRUE)cumsum(is_new_year)对标记结果累积求和,每遇到新年份计数加1,后续同一年份的记录保持当前计数,符合你示例中「nYear最终为2」的需求。
原代码问题分析
- 分组错误:你按
Country, Site, Species, Year分组,导致每组仅包含同一年的记录,无法跨年份计算累积值。 - 逻辑错误:
Year[Species %in% Site]是将物种编号与站点字母做匹配,两者取值类型完全不相关,返回空向量,因此n_distinct()结果为0。
内容的提问来源于stack exchange,提问作者RGR_288
相关产品推荐
相关产品推荐

