R语言基于DATE字段计算多列差分实现累计值转日度度量
可以通过两种常用方式实现符合规则的分组差分计算,结果和你给出的示例输出完全匹配:
基于dplyr(tidyverse生态,适配tibble格式)实现
这是处理tibble数据最简洁的方式,逻辑清晰且不会被原始行顺序干扰计算结果:
library(dplyr) # 你提供的原始tibble数据 raw_data <- structure(list(new_col = c(1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7), DATE = structure(c(1608249600, 1608249600, 1608249600, 1608249600, 1608249600, 1608249600, 1608249600, 1608336000, 1608336000, 1608336000, 1608336000, 1608336000, 1608336000, 1608336000, 1608422400, 1608422400, 1608422400, 1608422400, 1608422400, 1608422400, 1608422400), tzone = "UTC", class = c("POSIXct", "POSIXt")), HOSP_COUNT = c(582, 931, 1472, 2175, 2791, 3024, 2310, 588, 932, 1477, 2186, 2810, 3051, 2330, 590, 932, 1479, 2188, 2817, 3060, 2335)), row.names = c(NA, -21L), class = c("tbl_df", "tbl", "data.frame")) # 分组差分计算 result <- raw_data %>% # 按new_col拆分为独立计算分组 group_by(new_col) %>% # 组内严格按DATE升序排序,避免乱序导致计算错误 arrange(DATE, .by_group = TRUE) %>% mutate( # 计算当前值与同组上一日期累计值的差值 daily_hosp = HOSP_COUNT - lag(HOSP_COUNT), # 每个分组的第一个日期没有前置值,直接保留原始累计值 daily_hosp = ifelse(is.na(daily_hosp), HOSP_COUNT, daily_hosp) ) %>% ungroup()
如果需要完全匹配你给出的期望输出结构,只需将计算得到的daily_hosp列重命名为HOSP_COUNT即可。
基础R实现(无需加载额外包)
不依赖第三方包时,可通过基础函数实现相同逻辑,核心是先基于new_col和DATE字段完成排序,再逐组计算差分:
# 先按分组和日期对全量数据排序 sorted_data <- raw_data[order(raw_data$new_col, raw_data$DATE), ] # 逐组计算日度量值,每组首个值保留原始累计值 sorted_data$daily_hosp <- with( sorted_data, ave(HOSP_COUNT, new_col, FUN = function(x) c(x[1], diff(x))) )
关键注意点
- 所有差分操作必须基于
DATE字段完成组内排序,不能直接依赖数据集自带的行顺序,一旦行序错乱,差分结果会完全失真- 目前逻辑默认每个分组下连续日期都有对应记录,如果存在日期缺失,需要先补全缺失日期的累计值(一般用前值填充)再做差分,否则会把跨多天的累计差误判为单日增量
- 计算结果建议先保留为新列,不要直接覆盖原始累计值,方便后续校验计算逻辑
内容的提问来源于stack exchange,提问作者Ali Roghani
相关产品推荐
相关产品推荐

