这是一个简化的数据示例。
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,如果 is.na(SU) == TRUE,使用 TIME 减去之前的 AMT 而不是 NA 行的 TIME。
这就是我想要的。
苏 | 时间 | AMT | TFDS |
---|---|---|---|
1 | 10 | 5 | 不适用 |
1 | 20 | 5 | 不适用 |
不适用 | 30 | 不适用 | 10 |
不适用 | 40 | 不适用 | 20 |
不适用 | 50 | 5 | 30 |
不适用 | 60 | 5 | 10 |
我尝试了 dplyr::lag,但输出不是我想要的。
library(dplyr)
df = df |> mutate(
TFDS = if_else(
is.na(SU) == TRUE, TIME - lag(TIME)[!is.na(AMT)], NA
))
我相信 dplyr::lag 应该在那里使用,但是如何设置 [!is.na(AMT)] ?
您可以创建一个临时列并使用
tidyr::fill()
从最后一个非 NA SU 值开始填充,然后使用 lag()
减去值:
library(dplyr)
library(tidyr)
df |>
mutate(tmp = if_else(!is.na(AMT), TIME, NA)) |>
fill(tmp, .direction = "down") |>
mutate(TFDS = if_else(is.na(SU), TIME - lag(tmp), NA)) |>
select(-tmp)
# SU TIME AMT tmp TFDS
# 1 1 10 5 10 NA
# 2 1 20 5 20 NA
# 3 NA 30 NA 20 10
# 4 NA 40 NA 20 20
# 5 NA 50 5 50 30
# 6 NA 60 5 60 10