如何追踪R语言数据框各行数据变化并新增对应标识列?
R 实现按ID定位数值首次变化年份的方案
核心处理逻辑:
- 按年份顺序提取所有年度数值列
- 逐行比较相邻年度的数值,定位第一个出现差异的位置
- 按位置填充变化标记、变化年份、变化前后值,无变化则统一填充0
方法1:dplyr 实现(可读性高)
library(dplyr) # 构造原始输入数据框 df <- data.frame( ID = c(123100,123200,123300,123400,123500), `2014` = c(1,1,1,2,3), `2015` = c(1,1,1,2,3), `2016` = c(2,1,1,2,1), `2017` = c(2,1,1,2,1), `2018` = c(2,3,1,2,1), check.names = FALSE ) # 指定年度列的顺序 year_cols <- as.character(2014:2018) df_final <- df %>% rowwise() %>% mutate( diff_pos = which(diff(c_across(all_of(year_cols))) != 0)[1], change = ifelse(is.na(diff_pos), 0, 1), year = ifelse(is.na(diff_pos), 0, as.numeric(year_cols[diff_pos + 1])), before = ifelse(is.na(diff_pos), 0, c_across(all_of(year_cols))[diff_pos]), after = ifelse(is.na(diff_pos), 0, c_across(all_of(year_cols))[diff_pos + 1]) ) %>% select(-diff_pos) %>% ungroup()
运行后输出结果和预期完全一致:
> print(df_final) # A tibble: 5 × 9 ID `2014` `2015` `2016` `2017` `2018` change year before after <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 123100 1 1 2 2 2 1 2016 1 2 2 123200 1 1 1 1 3 1 2018 1 3 3 123300 1 1 1 1 1 0 0 0 0 4 123400 2 2 2 2 2 0 0 0 0 5 123500 3 3 1 1 1 1 2016 3 1
方法2:基础R实现(无依赖)
不需要加载第三方包,直接用基础函数即可完成计算:
year_cols <- as.character(2014:2018) year_mat <- as.matrix(df[, year_cols]) change_info <- t(apply(year_mat, 1, function(x){ diff_val <- diff(x) pos <- which(diff_val != 0)[1] if(is.na(pos)){ c(change=0, year=0, before=0, after=0) }else{ c(change=1, year=as.numeric(year_cols[pos+1]), before=x[pos], after=x[pos+1]) } })) df_final <- cbind(df, change_info)
注:上述代码默认取每个ID第一次出现数值变化的节点,和示例给出的预期规则一致;如果需要记录所有变化点,可以调整逻辑把行拆分为长表后处理。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

