如何基于TRUE/FALSE列计算条件差值?优先使用dplyr::mutate
解决方法:用dplyr实现动态差值计算
我明白你的需求了——要根据logic_col的状态动态计算time_col的差值,核心是在上一行是TRUE时重置基准,在上一行是FALSE时沿用最近的TRUE行或起始逻辑作为基准。下面是用dplyr(结合tidyr的fill函数)实现的完整方案,完全匹配你的测试数据预期:
首先,先确认你的测试数据:
dat <- data.frame( logic_col = c(F, F, T, T, F, F, F, T, F), time_col = c(200, 435, 567, 895, 1012, 1345, 1456, 1700, 1900), expected_col_unseen = c(200, 435, 567, 328, 117, 450, 561, 805, 200) )
然后是实现代码:
library(dplyr) library(tidyr) dat_result <- dat %>% # 第一步:标记并填充最近的TRUE行的time_col mutate(last_true = ifelse(logic_col, time_col, NA)) %>% fill(last_true, .direction = "down") %>% # 把最近的TRUE值向下传递给后续FALSE行 replace_na(list(last_true = 0)) %>% # 开头未出现TRUE的行,基准设为0 # 第二步:根据规则计算差值 mutate( calculated_col = case_when( # 上一行是TRUE,当前行也是TRUE:差值重置为当前减上一行time_col logic_col & lag(logic_col, default = FALSE) ~ time_col - lag(time_col), # 上一行是FALSE,当前行是TRUE:用当前time_col减最近的TRUE值(或0) logic_col & !lag(logic_col, default = FALSE) ~ time_col - last_true, # 当前行是FALSE:用当前time_col减最近的TRUE值 TRUE ~ time_col - last_true ) )
运行后查看结果,calculated_col会和你的expected_col_unseen完全一致:
dat_result %>% select(logic_col, time_col, expected_col_unseen, calculated_col) # logic_col time_col expected_col_unseen calculated_col # 1 FALSE 200 200 200 # 2 FALSE 435 435 435 # 3 TRUE 567 567 567 # 4 TRUE 895 328 328 # 5 FALSE 1012 117 117 # 6 FALSE 1345 450 450 # 7 FALSE 1456 561 561 # 8 TRUE 1700 805 805 # 9 FALSE 1900 200 200
代码逻辑解释
last_true列的作用:- 先给所有
TRUE行标记对应的time_col,其他行留空(NA)。 - 用
fill向下填充NA,让每个FALSE行都能获取到最近的上一个TRUE行的time_col。 - 开头还没出现
TRUE的行,把基准设为0,这样差值就是自身的time_col,匹配你的预期。
- 先给所有
case_when的条件分支:- 针对连续
TRUE的情况:上一行是TRUE时,差值重置为当前行减上一行的time_col,符合你“差值需重置”的要求。 - 针对首次出现
TRUE的情况:上一行是FALSE时,用当前time_col减去最近的TRUE值(如果是第一个TRUE则减0)。 - 针对
FALSE行:直接用当前time_col减去最近的TRUE值,延续基准计算差值。
- 针对连续
内容的提问来源于stack exchange,提问作者jackbio
相关产品推荐
相关产品推荐

