带缺失值的ID分组时间序列1/0状态切换次数统计的R代码需求
按个体统计二分类状态切换次数(含缺失值处理)
嘿,针对你提出的带缺失值的时间序列数据,需要统计每个ID在1和0之间的状态切换次数,这里提供两种常用的R实现方法,都能妥善处理随机缺失值:
方法一:使用dplyr进行分组处理
先加载必要的包,然后按ID分组,清理缺失值后计算切换次数:
# 若未安装dplyr,先运行 install.packages("dplyr") library(dplyr) # 构造你的示例数据 id=c(1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4) indicator=c(1,0,0,0,1,1,NA,1,1,0,1,0,NA,1,1,0) timepoint=c(2003,2004,2005,2006) td = data.frame(id,timepoint,indicator) # 统计每个个体的状态切换次数 switch_counts <- td %>% group_by(id) %>% # 过滤当前个体的缺失观测,保证时间顺序(若数据无序可加 arrange(timepoint)) filter(!is.na(indicator)) %>% # 对比当前与前一个时间点的状态,不同则标记为1(切换) mutate(switch = ifelse(indicator != lag(indicator), 1, 0)) %>% # 对切换标记求和,自动忽略第一个观测的NA(lag无前置值) summarise(total_switches = sum(switch, na.rm = TRUE)) %>% ungroup() # 查看结果 print(switch_counts)
代码说明
group_by(id):按个体ID分组,保证每个ID独立计算filter(!is.na(indicator)):移除当前个体的缺失值,避免干扰切换判断mutate(switch = ...):用lag()获取前一个时间点的状态,与当前状态对比,差异不为0则标记为切换summarise(total_switches = ...):对每个ID的切换标记求和,na.rm=TRUE忽略无效的NA值
方法二:基础R实现(无需额外包)
如果不想加载第三方包,用基础R也能轻松实现:
# 构造你的示例数据 id=c(1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4) indicator=c(1,0,0,0,1,1,NA,1,1,0,1,0,NA,1,1,0) timepoint=c(2003,2004,2005,2006) td = data.frame(id,timepoint,indicator) # 按ID拆分数据为列表 split_td <- split(td, td$id) # 定义计算单个ID切换次数的函数 count_switches <- function(df) { # 提取当前个体的有效状态(过滤缺失值) valid_indicators <- df$indicator[!is.na(df$indicator)] # 若有效观测少于2次,切换次数为0 if(length(valid_indicators) < 2) return(0) # 计算相邻状态的差值,统计非0的数量(即切换次数) sum(diff(valid_indicators) != 0) } # 对每个ID应用函数并整理结果 switch_counts_base <- sapply(split_td, count_switches) switch_counts_base <- data.frame(id = names(switch_counts_base), total_switches = as.numeric(switch_counts_base)) # 查看结果 print(switch_counts_base)
代码说明
split(td, td$id):将数据按ID拆分为子数据集列表,每个元素对应一个个体count_switches函数:先清理缺失值,若有效观测不足2次直接返回0;用diff()计算相邻状态的差值,差值不为0代表发生切换,统计这类情况的总数sapply():批量将函数应用到每个ID的子数据上
两种方法得到的结果完全一致,比如ID3的有效状态序列是[1,0,1,0],切换次数为3;ID4的有效状态序列是[1,1,0],切换次数为1,都能被正确计算。
内容的提问来源于stack exchange,提问作者David Eagle
相关产品推荐
相关产品推荐

