在R中如何将相同ID下valid_until列末值替换为首行值并仅保留首行
R实现按ID合并行的解决方案
测试数据构造
你可以先用以下代码构造和示例一致的测试数据验证效果:
df <- read.table(text = "ID valid_from valid_until action action_text 1 01/01/2010 31/01/2016 1 Text1 1 01/02/2016 01/01/2021 2 Text2 2 01/10/2010 30/09/2019 4 Text4 3 01/05/2015 31/12/2015 3 Text3 3 01/01/2016 30/09/2020 3 Text3", header = TRUE, stringsAsFactors = FALSE)
方法1:dplyr实现(推荐,代码简洁易读)
针对15000行的数据集运行效率极高,代码逻辑和需求完全匹配:
library(dplyr) result <- df %>% # 按ID分组 group_by(ID) %>% # 先将每组的valid_until统一替换为组内最后一行的取值 mutate(valid_until = last(valid_until)) %>% # 仅保留每组的第一行 slice_head(n = 1) %>% # 取消分组 ungroup()
如果你的数据集列数很多,不需要额外修改代码,以上逻辑通用。
方法2:Base R实现(无需加载第三方包)
如果你不想安装额外的R包,可以用原生语法实现:
# 按ID拆分数据集,逐个分组处理后再合并 result <- do.call(rbind, lapply(split(df, df$ID), function(group_df) { # 把分组第一行的valid_until替换为分组最后一行的取值 group_df[1, "valid_until"] <- group_df[nrow(group_df), "valid_until"] # 仅返回分组第一行 return(group_df[1, ]) })) # 重置结果的行号 rownames(result) <- NULL
额外提示
如果后续需要对时间列做计算,建议先把字符格式的时间转成R的日期格式:
df$valid_from <- as.Date(df$valid_from, format = "%d/%m/%Y") df$valid_until <- as.Date(df$valid_until, format = "%d/%m/%Y")
内容的提问来源于stack exchange,提问作者Besz15
相关产品推荐
相关产品推荐

