如何用R语言的ave()和seq_along()函数按组生成上一日期列
R语言分组获取上一条记录日期问题解决
问题说明
我是R语言初学者,尝试用ave()和seq_along()函数给数据框按name分组添加一列prev_date_name,存储同组内上一条记录的日期,但运行结果不符合预期。
期望输出
name date prev_date_name 1 aaa 2000-01-01 <NA> 2 aaa 2000-01-02 2000-01-01 3 bbb 2000-01-03 <NA> 4 bbb 2000-01-04 2000-01-03 5 bbb 2000-01-05 2000-01-04 6 bbb 2000-01-05 2000-01-05 7 eee 2000-01-06 <NA> 8 eee 2000-01-07 2000-01-06 9 eee 2000-01-08 2000-01-07
错误代码与实际输出
错误代码
# 创建数据框 name <- c('aaa', 'aaa', 'bbb', 'bbb', 'bbb', 'bbb', 'eee', 'eee', 'eee') date <- c('2000-01-02', '2000-01-01', '2000-01-03', '2000-01-04', '2000-01-05', '2000-01-05', '2000-01-06', '2000-01-07', '2000-01-08') list_names <- data.frame(name, date) # 按日期排序 list_names <- arrange(list_names, date) # 添加同组上一条日期列 list_names$prev_date_name <- ave(list$date, list$name, FUN = function(x) ifelse(seq_along(x)==1, NA, x[as.integer(seq_along(x))-1])) print(list_names)
实际输出
name date prev_date_name 1 aaa 2000-01-01 <NA> 2 aaa 2000-01-02 2000-01-01 3 bbb 2000-01-03 <NA> 4 bbb 2000-01-04 2000-01-04 5 bbb 2000-01-05 2000-01-05 6 bbb 2000-01-05 2000-01-03 7 eee 2000-01-06 <NA> 8 eee 2000-01-07 2000-01-06 9 eee 2000-01-08 2000-01-06
问题分析与修正代码
问题点
- 变量名笔误:代码中错误使用了
list$date和list$name,实际数据框名为list_names; - 排序逻辑错误:仅按全局日期排序,未先按
name分组再组内排序,导致ave()处理分组时,同组记录的顺序不符合预期; - FUN函数逻辑复杂易出错:用
ifelse结合seq_along的写法,在索引处理时容易出现错位。
修正后的代码
# 加载dplyr包(arrange函数需要) library(dplyr) # 创建数据框 name <- c('aaa', 'aaa', 'bbb', 'bbb', 'bbb', 'bbb', 'eee', 'eee', 'eee') date <- c('2000-01-02', '2000-01-01', '2000-01-03', '2000-01-04', '2000-01-05', '2000-01-05', '2000-01-06', '2000-01-07', '2000-01-08') list_names <- data.frame(name, date) # 先按name分组,再组内按date排序 list_names <- arrange(list_names, name, date) # 添加同组上一条日期列 list_names$prev_date_name <- ave(list_names$date, list_names$name, FUN = function(x) c(NA, x[-length(x)])) print(list_names)
代码解释
- 排序时先按
name分组,再按date排序,确保同组记录按日期顺序排列; - 修正变量名,使用正确的
list_names数据框; - 简化FUN函数:
c(NA, x[-length(x)])直接为每个分组生成上一条记录,第一个元素设为NA,后续元素取前一个位置的日期,逻辑清晰且不易出错。
内容的提问来源于stack exchange,提问作者BMUIS
相关产品推荐
相关产品推荐

