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

基于多条件的唯一值累积求和及物种观测统计问题

解决方案

首先构造贴近实际场景的测试数据(包含同一物种-站点-年份的多条记录):

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()

代码说明

  1. 分组逻辑:必须按Country, Site, species分组,才能在同一物种-站点的范围内计算累积值,避免跨组干扰。
  2. 排序:按Year排序是累积计算的前提,确保统计是按时间顺序逐步累加。
  3. Spsum计算:row_number()在分组内从1开始递增,正好对应到当前行的累积记录总数,完全匹配你示例中「1981年5次、1982年2次,Spsum最终为7」的需求。
  4. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 07:07:03