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

如何在R中从相同值的日期范围生成新的Data Frame

问题

现有如下R语言DataFrame示例:

structure(list(date = structure(c(1514764800, 1514851200, 1514937600, 1515024000, 1515110400, 1515196800, 1515283200, 1515369600, 1515456000, 1515542400, 1515628800, 1515715200, 1515801600, 1515888000, 1515974400, 1516060800, 1516147200, 1516233600, 1516320000, 1516406400, 1516492800, 1516579200, 1516665600, 1516752000, 1516838400, 1516924800, 1517011200, 1517097600, 1517184000, 1517270400, 1517356800, 1517443200, 1517529600, 1517616000, 1517702400, 1517788800, 1517875200, 1517961600, 1518048000, 1518134400, 1518220800, 1518307200, 1518393600, 1518480000, 1518566400), tzone = "UTC", class = c("POSIXct", "POSIXt")), Al = c(NA, 21.399, 21.399, 21.399, NA, NA, NA, 8.036, 8.036, 8.036, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 36.914, 36.914, 36.914, NA, NA, NA, 11.466, 11.466, 11.466, NA, NA, NA, NA, NA, 16.471, 16.471, 16.471, NA, NA, NA, NA, 56.157, 56.157, 56.157)), row.names = c(NA, -45L), class = c("tbl_df", "tbl", "data.frame"))

需要生成新的DataFrame,仅保留相同值连续日期范围的首个日期,预期输出如下:

structure(list(startdate = structure(c(17532, 17533, 17536, 17539, 17542, 17553, 17556, 17559, 17562, 17567, 17570, 17574), class = "Date"), Al = c(NA, 21.399, NA, 8.036, NA, 36.914, NA, 11.466, NA, 16.471, NA, 56.157)), class = c("spec_tbl_df", "tbl_df", "tbl", "data.frame"), row.names = c(NA, -12L), spec = structure(list(cols = list(startdate = structure(list(format = "%m/%d/%Y"), class = c("collector_date", "collector")), Al = structure(list(), class = c("collector_double", "collector"))), default = structure(list(), class = c("collector_guess", "collector")), skip = 1), class = "col_spec"))

需用R语言处理大量此类数据集。

解决方案

可以使用dplyr包实现需求,核心思路是为连续相同值(包括NA)的分组分配唯一ID,然后按分组筛选每组的首个日期:

代码实现

library(dplyr)

# 读取原始数据(假设原始数据名为df)
df <- structure(list(date = structure(c(1514764800, 1514851200, 1514937600, 1515024000, 1515110400, 1515196800, 1515283200, 1515369600, 1515456000, 1515542400, 1515628800, 1515715200, 1515801600, 1515888000, 1515974400, 1516060800, 1516147200, 1516233600, 1516320000, 1516406400, 1516492800, 1516579200, 1516665600, 1516752000, 1516838400, 1516924800, 1517011200, 1517097600, 1517184000, 1517270400, 1517356800, 1517443200, 1517529600, 1517616000, 1517702400, 1517788800, 1517875200, 1517961600, 1518048000, 1518134400, 1518220800, 1518307200, 1518393600, 1518480000, 1518566400), tzone = "UTC", class = c("POSIXct", "POSIXt")), Al = c(NA, 21.399, 21.399, 21.399, NA, NA, NA, 8.036, 8.036, 8.036, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 36.914, 36.914, 36.914, NA, NA, NA, 11.466, 11.466, 11.466, NA, NA, NA, NA, NA, 16.471, 16.471, 16.471, NA, NA, NA, NA, 56.157, 56.157, 56.157)), row.names = c(NA, -45L), class = c("tbl_df", "tbl", "data.frame"))

# 处理步骤
result_df <- df %>%
  # 为连续相同值(含NA)生成分组ID
  mutate(group_id = cumsum(ifelse(is.na(Al) != is.na(lag(Al, default = !is.na(first(Al)))), 1, 0)) %>%
           # 当Al值变化时,分组ID加1(区分非NA的不同值)
           + cumsum(ifelse(!is.na(Al) & Al != lag(Al, default = first(Al)), 1, 0))) %>%
  # 按分组ID筛选每组首个记录
  group_by(group_id) %>%
  slice(1) %>%
  ungroup() %>%
  # 重命名日期列,并保留需要的列
  rename(startdate = date) %>%
  select(startdate, Al) %>%
  # 转换日期格式为Date类型(匹配预期输出)
  mutate(startdate = as.Date(startdate))

# 查看结果
result_df

代码说明

  • group_id的生成:分两部分,第一部分区分连续的NA和非NA组,第二部分区分非NA情况下的不同数值组,确保所有连续相同值(包括连续NA)都被分到同一组。
  • slice(1)用于提取每组的第一条记录,即连续相同值范围的首个日期。
  • 最后转换日期格式为Date类型,与预期输出一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 09:41:02