R语言逐时点统计时间序列中各level的ID出现频次
R实现逐行更新各level ID计数的方案
核心逻辑
需求本质是按时间顺序逐行追踪状态迁移:初始4个ID全部处于level 0,每发生一次ID的level变动,就将迁出level的计数减1、迁入level的计数加1,每一行的计数结果完全基于上一行的状态更新。
简洁实现代码
优先用可读性最高、性能无劣势的显式迭代写法,逻辑简单易调试:
library(tibble) # 构造示例输入数据 df <- tibble(ID = c(1, 2, 1, 3, 4, 1, 2, 3), level = c(0, 0, 1, 2, 1, 2, 3, 0), n_0 = 4, n_1 = 0, n_2 = 0, n_3 = 0, previous_level = c(0, 0, 0, 0, 0, 1, 0, 2)) # 逐行更新计数 for (i in 2:nrow(df)) { # 继承上一行的计数结果 df[i, c("n_0", "n_1", "n_2", "n_3")] <- df[i-1, c("n_0", "n_1", "n_2", "n_3")] # 迁出的旧level计数-1 old_col <- paste0("n_", df$previous_level[i]) df[i, old_col] <- df[i, old_col] - 1 # 迁入的新level计数+1 new_col <- paste0("n_", df$level[i]) df[i, new_col] <- df[i, new_col] + 1 }
结果验证
运行上述代码后输出的df和预期结果完全一致:
# A tibble: 8 × 7 ID level n_0 n_1 n_2 n_3 previous_level <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 1 0 4 0 0 0 0 2 2 0 4 0 0 0 0 3 1 1 3 1 0 0 0 4 3 2 2 1 1 0 0 5 4 1 1 2 1 0 0 6 1 2 1 1 2 0 1 7 2 3 0 1 2 1 0 8 3 0 1 1 1 1 2
补充说明
- 该实现时间复杂度为O(n),即使十万级以上数据量也能快速运行,没有冗余计算
- 如果偏好函数式写法避免显式循环,也可以用
purrr::accumulate实现累积更新,逻辑和上述for循环完全一致,结果相同 - 不需要提前手动初始化n系列列也可以运行,直接从初始状态
c(4,0,0,0)开始迭代即可
内容的提问来源于stack exchange,提问作者Ai4l2s
相关产品推荐
相关产品推荐

