You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言实现动态自引用的tenure列生成(无for循环)

在R的data.frame中生成按条件递增的ten列(无for循环实现)

需求:给data.frame新增ten列,初始值为1;若当前行的occ与前一行的occPrev相等,ten递增1;若不相等则重置为1。要求避免使用for循环,同时支持按id分组的通用场景。

示例数据

df <- data.frame(
  id = c(1,1,1,2,2,2),
  occ = c("A", "A", "B", "C", "C", "C"),
  occPrev = c("A", "A", "A", "C", "D", "C")
)

期望输出

expected_df <- data.frame(
  id = c(1,1,1,2,2,2),
  occ = c("A", "A", "B", "C", "C", "C"),
  occPrev = c("A", "A", "A", "C", "D", "C"),
  ten = c(1,2,1,1,1,1)
)

解决方案(dplyr + rle)

利用rle(游程编码)处理连续重复的逻辑,结合dplyr的分组功能,完美实现无循环需求:

library(dplyr)

df_result <- df %>%
  group_by(id) %>%
  mutate(
    # 标记当前行与前一行的occ/occPrev是否相等
    is_same = occ == occPrev,
    # 对连续相等的标记生成递增序号
    seq_id = inverse.rle(within.list(rle(is_same), values <- seq_along(values))),
    # 根据标记生成ten列:相等时用递增序号,否则重置为1
    ten = ifelse(is_same, seq_id, 1)
  ) %>%
  ungroup() %>%
  select(-is_same, -seq_id) # 清理中间变量

简化版(省略中间变量)

如果不需要保留中间标记列,可以直接整合逻辑:

df_result <- df %>%
  group_by(id) %>%
  mutate(
    ten = ifelse(occ == occPrev, 
                 inverse.rle(within.list(rle(occ == occPrev), values <- seq_along(values))),
                 1)
  ) %>%
  ungroup()

运行后df_result的ten列将完全匹配期望输出,且支持任意多分组场景,效率远高于for循环。

内容的提问来源于stack exchange,提问作者ykkoca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 07:32:36