R语言生成TFDS列:SU为NA时用TIME减前一个非NA的AMT行TIME
解决方案
要实现你需要的TFDS列,核心是先获取每行最近的、位于当前行之前的AMT非NA对应的TIME值,再进行计算。你之前的lag(TIME)[!is.na(AMT)]逻辑有误,因为它是基于当前行的AMT状态来索引滞后的TIME,而非追踪最近的有效AMT行。
具体实现代码
library(dplyr) library(tidyr) # 原始数据 df <- data.frame( SU = c(1, 1, NA, NA, NA, NA), TIME = c(10, 20, 30, 40, 50, 60), AMT = c(5, 5, NA, NA, 5, 5) ) # 生成TFDS列 df <- df %>% # 临时列:仅保留AMT非NA的TIME,其余为NA mutate(last_valid_amt_time = if_else(!is.na(AMT), TIME, NA_integer_)) %>% # 向下填充临时列,让每一行都拿到最近的上一个有效AMT对应的TIME fill(last_valid_amt_time, .direction = "down") %>% # 按规则计算TFDS mutate(TFDS = if_else(is.na(SU), TIME - last_valid_amt_time, NA_integer_)) %>% # 移除临时列(可选) select(-last_valid_amt_time)
结果验证
运行后得到的结果与你期望的一致:
| SU | TIME | AMT | TFDS |
|---|---|---|---|
| 1 | 10 | 5 | NA |
| 1 | 20 | 5 | NA |
| NA | 30 | NA | 10 |
| NA | 40 | NA | 20 |
| NA | 50 | 5 | 30 |
| NA | 60 | 5 | 10 |
逻辑说明
- 临时列创建:
last_valid_amt_time只保留AMT非NA行的TIME,其他行设为NA,标记出所有有效时间点。 - 向下填充:
fill()函数会把最近的非NA值向下填充,确保每一行都能获取到它之前最近的有效AMT时间。 - 计算TFDS:判断SU是否为NA,若是则用当前TIME减去填充后的有效时间,否则设为NA。
内容的提问来源于stack exchange,提问作者Dylan Li
相关产品推荐
相关产品推荐

