如何用R计算非平衡面板数据每年新增和流失的个体数量
非平衡面板数据:统计年度新增/流失个体数量
需求与示例
我有非平衡面板数据,需要统计每年新增个体数量和流失个体数量。
示例数据
Year <- c(2009, 2009, 2009, 2010, 2010, 2010) ID <- c("A", "A", "B", "B", "D", "C") df <- data.frame(Year, ID)
期望结果
| Year | Nr. Added | Nr. Removed |
|---|---|---|
| 2009 | 2 | NA |
| 2010 | 2 | 1 |
对应的数据结构:
structure(list(Year = c(2009, 2010), `Nr. Added` = c(2, 2), `Nr. Removed` = c(NA, 1)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -2L))
现有代码问题
我当前的代码仅能识别首次出现的个体,但无法处理消失后重现的个体,也不知道如何统计年度流失个体:
y <- split(df$, arranged_data$year) z<- data.frame(Year = names(y), nNew = diff(lengths(Reduce(union, y, NULL, accumulate = TRUE))))
解决方案
通过以下步骤可以实现需求,同时解决个体消失后重现的统计问题:
- 先对原始数据按年度去重,得到每个年度的唯一ID集合
- 按年度排序后,依次对比当前年度与上一年度(或之前所有年度)的ID集合,计算新增和流失数量
完整代码
library(dplyr) # 1. 按年度去重,得到每年的唯一ID列表 yearly_ids <- df %>% distinct(Year, ID) %>% arrange(Year) %>% group_split(Year, .keep = FALSE) %>% setNames(unique(df$Year)) # 2. 计算新增、流失数量 result <- tibble(Year = as.integer(names(yearly_ids))) %>% mutate( # 新增:仅统计首次出现的个体(消失后重现不算新增) `Nr. Added` = map_int(seq_along(yearly_ids), ~{ current_ids <- yearly_ids[[.x]]$ID if (.x == 1) { length(current_ids) } else { # 合并之前所有年度的ID,取当前年度独有的部分 all_previous_ids <- reduce(yearly_ids[1:(.x-1)], ~union(.x$ID, .y$ID)) length(setdiff(current_ids, all_previous_ids)) } }), # 流失:上一年度存在但当前年度不存在的个体数 `Nr. Removed` = map_int(seq_along(yearly_ids), ~{ if (.x == 1) { NA_integer_ } else { prev_year_ids <- yearly_ids[[.x-1]]$ID current_ids <- yearly_ids[[.x]]$ID length(setdiff(prev_year_ids, current_ids)) } }) ) result
代码说明
distinct(Year, ID):避免同一年度内重复ID干扰计数- 新增数量逻辑:首次年度直接统计唯一ID数;后续年度对比之前所有年度的ID集合,仅将首次出现的个体计入新增(即使个体后续消失再重现,也不会重复统计)
- 流失数量逻辑:对比上一年度与当前年度的ID集合,差值即为流失个体数
运行后可得到与期望完全一致的结果。
内容的提问来源于stack exchange,提问作者Michael Troege
相关产品推荐
相关产品推荐

