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

在R中计算分组职业暴露时长(去重重叠年份)遇报错求解决

职业暴露数据库分组暴露时长计算报错解决方法

问题背景

现有大型职业暴露数据库,需计算每个研究对象对试剂分组的总暴露时长,要求不同职业接触同一分组试剂时,重叠年份仅统计一次。原计算单试剂暴露时长的代码可正常运行,但将试剂分为M组(A、B)和N组(C、D)后,运行类似代码时出现报错。

报错信息

Error in `summarise()`: ! Problem while computing `year = seq(YEARIN, YEAROUT, by = 1)`. ℹ The error occurred in group 5: ID = 7, JOB = 1, AGENT_GROUP = "M". Caused by error in `seq.default()`: ! 'from' must be of length 1 Run `rlang::last_error()` to see where the error occurred.

数据结构

初始数据

structure(list(ID = c(2, 2, 2, 2, 7, 7, 15, 18, 18, 18, 18, 18, 
20, 20, 20), JOB = c(1, 2, 7, 8, 1, 1, 1, 1, 2, 4, 2, 3, 3, 4, 
6), AGENT = c("A", "A", "B", "B", "B", "A", "A", "D", "D", "D", 
"A", "A", "C", "C", "C"), YEARIN = c(1998, 1996, 1979, 1978, 
1973, 1973, 1979, 1976, 1980, 1970, 1978, 1984, 1988, 1996, 2000
), YEAROUT = c(2009, 2000, 1985, 1982, 2006, 2006, 2007, 1985, 
2008, 2005, 1979, 1995, 1993, 2002, 2008)), class = c("tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -15L))

分组后数据

structure(list(ID = c(2, 2, 2, 2, 7, 7, 15, 18, 18, 18, 18, 18, 
20, 20, 20), JOB = c(1, 2, 7, 8, 1, 1, 1, 1, 2, 4, 2, 3, 3, 4, 
6), AGENT = c("A", "A", "B", "B", "B", "A", "A", "D", "D", "D", 
"A", "A", "C", "C", "C"), YEARIN = c(1998, 1996, 1979, 1978, 
1973, 1973, 1979, 1976, 1980, 1970, 1978, 1984, 1988, 1996, 2000
), YEAROUT = c(2009, 2000, 1985, 1982, 2006, 2006, 2007, 1985, 
2008, 2005, 1979, 1995, 1993, 2002, 2008), AGENT_GROUP = c("M", 
"M", "M", "M", "M", "M", "M", "N", "N", "N", "M", "M", "N", "N", 
"N")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-15L))

原正常运行代码(单试剂计算)

datatest %>%    
  group_by(ID, JOB, AGENT) %>%    
  summarise(year = seq(YEARIN, YEAROUT, by=1)) %>%    
  unnest(year) %>%    
  group_by(ID, AGENT) %>%    
  summarise(nyear = length(unique(year))) 

问题原因

同一ID、JOB、AGENT_GROUP下存在重复行(如ID=7、JOB=1、AGENT_GROUP=M的两行,YEARIN和YEAROUT完全相同),导致seq()函数接收到长度大于1的from和to参数,触发报错(seq()要求输入为单个值)。

解决方案

方案1:先去重再计算

针对同一分组内时间区间完全重复的情况,先删除重复行,再执行原逻辑:

# 第一步:创建试剂分组字段
datatest <- datatest %>%
  mutate(AGENT_GROUP = case_when(
    AGENT %in% c("A", "B") ~ "M",
    AGENT %in% c("C", "D") ~ "N",
    TRUE ~ NA_character_
  ))

# 第二步:去重后计算分组暴露时长
datatest %>%
  distinct(ID, JOB, AGENT_GROUP, YEARIN, YEAROUT, .keep_all = TRUE) %>%
  group_by(ID, JOB, AGENT_GROUP) %>%
  summarise(year = seq(YEARIN, YEAROUT, by = 1), .groups = "drop_last") %>%
  unnest(year) %>%
  group_by(ID, AGENT_GROUP) %>%
  summarise(nyear = length(unique(year)), .groups = "drop")

方案2:直接合并所有时间区间(更通用)

不管组内是否有重复,直接生成所有年份序列后合并去重,适用于同一分组内存在不同时间区间的场景:

# 创建试剂分组字段
datatest <- datatest %>%
  mutate(AGENT_GROUP = case_when(
    AGENT %in% c("A", "B") ~ "M",
    AGENT %in% c("C", "D") ~ "N",
    TRUE ~ NA_character_
  ))

# 计算分组暴露时长
datatest %>%
  group_by(ID, AGENT_GROUP) %>%
  summarise(
    year = purrr::map2(YEARIN, YEAROUT, ~seq(.x, .y, by = 1)) %>% unlist(),
    .groups = "drop"
  ) %>%
  mutate(year = unique(year)) %>%
  group_by(ID, AGENT_GROUP) %>%
  summarise(nyear = n(), .groups = "drop")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 23:05:16