R数据框按sn分组基于历史行多条件更新delta_hours列问题
解决方案
你可以直接用dplyr的case_when搭配分组 lag 功能实现需求,代码如下:
首先加载依赖包:
library(dplyr)
处理代码:
df_result <- df %>% # 按sn、年份升序排序,保证同个sn的记录按时间先后排列 arrange(sn, year) %>% # 按sn分组,单独处理每个sn的历史数据 group_by(sn) %>% mutate( delta_hours = case_when( # 规则1:2021年之前的原有数值直接保留 year < 2021 ~ delta_hours, # 规则2:没有历史记录(lag取到空值)直接赋值为当前hours is.na(lag(hours)) ~ hours, # 规则3:有历史记录的用当前hours减去最近一次历史的hours值 TRUE ~ hours - lag(hours) ) ) %>% ungroup() %>% # 恢复原始数据的排序顺序(可选) arrange(year, sn)
运行后得到的结果和你给出的目标数据完全一致:
year sn hours delta_hours <dbl> <chr> <dbl> <dbl> 1 2019 AB1001 150 150 2 2019 AB1002 173 173 3 2020 AB1001 189 39 4 2020 DC1001 102 102 5 2021 AB1001 215 26 6 2021 AB1002 175 2 7 2021 AB1003 98 98
逻辑说明
lag()函数会返回分组内当前行的上一行指定列的值,我们提前按年份升序排列同sn的记录,所以上一行一定是该sn最近一次的历史记录,哪怕中间缺少年份也能正确取到最近值,完全匹配你的计算规则。
内容的提问来源于stack exchange,提问作者joerminer
相关产品推荐
相关产品推荐

