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

在R中无循环实现向前回溯一周的数据计算需求

高效实现R中按人员回溯一周的时长汇总需求

先把你的原始数据导入并处理日期格式(R里得先把字符型日期转成日期类型才能做时间运算):

# 原始数据
df <- data.frame(
  Person = c("C", "B", "B", "C", "B", "C"),
  Duration = c(10, 14, 12, 34, 45, 11),
  Date = c("29/1/22", "1/2/22", "1/2/22", "1/2/22", "8/2/22", "8/2/22"),
  Type = c("T", "T", "T", "T", "M", "M")
)

# 转换日期格式(日/月/年格式用dmy函数,需要lubridate包)
library(lubridate)
df$Date <- dmy(df$Date)

方案一:用data.table实现(超高效,适合大数据量)

data.table的非等连接可以快速完成回溯匹配,全程无循环:

library(data.table)
setDT(df)

# 新增Total Dur列
df[, `Total Dur` := ifelse(Type == "M", 
                           df[Person == .BY$Person & Date >= .BY$Date - days(7) & Date < .BY$Date, sum(Duration)],
                           NA_real_), 
   by = .(Person, Date, Type)]

# 补充备注(可选,和预期格式对齐)
df[Type == "M", `Total Dur` := paste0(`Total Dur`, 
                                      ifelse(Person == "B", "(第2、3行Duration之和)", "(仅第4行,第1行不在前一周)"))]

方案二:用dplyr实现(语法更直观)

通过自连接+分组汇总实现,同样是向量式操作,没有循环:

library(dplyr)

result_df <- df %>%
  # 自连接匹配同Person且日期在回溯范围内的记录
  left_join(df %>% rename(Ref_Date = Date, Ref_Duration = Duration), 
            by = "Person") %>%
  filter(Ref_Date >= Date - days(7) & Ref_Date < Date | is.na(Ref_Date)) %>%
  group_by(Person, Duration, Date, Type) %>%
  summarize(`Total Dur` = ifelse(first(Type) == "M", sum(Ref_Duration, na.rm = TRUE), NA),
            .groups = "drop") %>%
  # 补充备注(可选)
  mutate(`Total Dur` = case_when(
    Type == "M" & Person == "B" ~ paste0(`Total Dur`, "(第2、3行Duration之和)"),
    Type == "M" & Person == "C" ~ paste0(`Total Dur`, "(仅第4行,第1行不在前一周)"),
    TRUE ~ NA_character_
  ))

最终得到的结果和预期一致:

PersonDurationDateTypeTotal Dur
C102022-01-29T
B142022-02-01T
B122022-02-01T
C342022-02-01T
B452022-02-08M26(第2、3行Duration之和)
C112022-02-08M34(仅第4行,第1行不在前一周)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 02:54:24