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

如何在R中实现Stata的expand功能按工作年份扩展数据行?

在R中实现Stata的expand功能:按工作年份拆分数据行

我有一份包含参与者ID、工作编号、工作开始日期、工作结束日期的数据集,想要为每份工作的每个工作年份新增一行。已知Stata中可以用expand finish_time-start_time + 1实现,但我用R语言,不知道怎么实现相同需求。

示例数据

data <- data.frame(id = c(1,1,2,3),
                   job = c(1,2,1,1),
                   start_time = seq(as.Date('2017-01-01'), as.Date('2020-01-01'), by = 'years'),
                   finish_time = seq(as.Date('2020-12-01'), as.Date('2023-12-01'), by = 'years'))

预期输出

每条原始数据行扩展为对应年份数量的行,新增expand列标记序号,示例格式如下:

idjobstart_timefinish_timeexpand
112017-01-012020-12-011
112017-01-012020-12-012
112017-01-012020-12-013
112017-01-012020-12-014
122018-01-012021-12-011
...............

解决方案

方法1:使用tidyverse(dplyr + tidyr)

通过计算年份差生成扩展次数,再拆分列表实现行扩展:

library(tidyverse)

data_expanded <- data %>%
  # 计算需扩展的行数(年份差+1)
  mutate(expand_count = lubridate::year(finish_time) - lubridate::year(start_time) + 1) %>%
  # 生成每行对应的序号列表
  mutate(expand = map(expand_count, ~1:.x)) %>%
  # 拆分列表为多行
  unnest(expand) %>%
  # 移除临时计算列
  select(-expand_count)

print(data_expanded)

若不想依赖lubridate,可替换年份提取逻辑为:as.POSIXlt(start_time)$year + 1900。

方法2:使用base R

无需额外包,通过行索引重复和序号生成实现:

# 计算每行扩展行数
expand_counts <- as.integer(format(data$finish_time, "%Y")) - as.integer(format(data$start_time, "%Y")) + 1

# 生成重复的行索引
row_indices <- rep(seq(nrow(data)), expand_counts)

# 扩展数据框并添加序号列
data_expanded_base <- data[row_indices, ]
data_expanded_base$expand <- unlist(lapply(expand_counts, seq_len))

print(data_expanded_base)

方法3:使用data.table(大数据高效处理)

针对大型数据集,data.table的实现速度更优:

library(data.table)

setDT(data)[, .(expand = 1:(year(finish_time) - year(start_time) + 1)), 
            by = .(id, job, start_time, finish_time)]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 10:55:02