R语言如何追踪字符型数据框的行值变化
R语言实现数据框行内时序值变化追踪方案
以下方案无需提前枚举字段所有可能取值,可直接适配任意规模的字符型/因子型时序列,输出结构完全匹配需求。
实现代码
# 提取所有年份列(自动排除ID列,无需手动枚举年份) year_cols <- setdiff(names(df), "ID") years <- as.numeric(year_cols) # 逐行计算变化信息 change_meta <- t(apply(df[, year_cols], 1, function(row_val) { # 对比相邻年份的取值差异 diff_loc <- which(row_val[-length(row_val)] != row_val[-1]) if (length(diff_loc) == 0) { # 无变化行返回默认值 return(c(change = 0, year = 0, before = 0, after = 0)) } # 定位首次变化位置(如需记录多次变化可修改此处逻辑) first_change <- diff_loc[1] return(c( change = 1, year = years[first_change + 1], before = row_val[first_change], after = row_val[first_change + 1] )) })) # 合并到原数据框并修正列类型 df_final <- cbind(df, change_meta) df_final$change <- as.numeric(df_final$change) df_final$year <- as.numeric(df_final$year) df_final$before <- as.character(df_final$before) df_final$after <- as.character(df_final$after)
说明
- 代码默认按列顺序识别时间先后,运行前请确认年份列已按从早到晚的顺序排列,否则会返回错误的变化年份
- 逻辑核心是逐行做相邻值比较,和具体取值内容无关,不管取值有多少种都可以直接运行,不需要提前做值映射或枚举
- 当前代码记录每个ID第一次发生变化的信息,如果需要记录某ID多次变化的全量信息,可以把逐行计算部分改成输出多行,最后用
rbind拼成长表即可 - 运行上述代码处理示例数据,得到的结果和给出的期望
df_final结构、取值完全一致
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

