我有一个包含 45k 多行的数据框,其中包含 ID
SE441
和年份 NUM_EXPLOTACION
的变量 ANO
的值。
我想计算每年和上一年之间每个ID的变量差异。问题是某些 ID 缺少年份,因此使用
lag
函数似乎不是我的解决方案。
我想要实现的一个例子是:
ANO NUM_EXPLOTACION SE441 diff
2017 657 12 NA
2018 657 15 3
2020 657 13 NA
2018 123 1 NA
2019 123 4 3
2020 123 0 -4
示例数据框:
macro <- data.frame(ANO=c(2017,2018,2020,2018,2019,2020), NUM_EXPLOTACION=c(657,657,657,123,123,123), SE441=c(12,15,13,1,4,0))
这是一个嵌套的 for 循环,我相信它可以完成这项工作,但它花费的时间太长,因此不可行:
for (i in min(macro$NUM_EXPLOTACION):max(macro$NUM_EXPLOTACION)) {
for (j in min(macro$ANO)+1:max(macro$ANO)) {
macro$diff[macro$NUM_EXPLOTACION==i & macro$ANO==j] <- if (length(macro$SE441[macro$NUM_EXPLOTACION==i & macro$ANO==j-1])) macro$SE441[macro$NUM_EXPLOTACION==i & macro$ANO==j] - macro$SE441[macro$NUM_EXPLOTACION==i & macro$ANO==j-1] else NA
}
}
在上面的代码中,我使用
min(macro$ANO)+1
来避免尝试使用不存在的值(第一个值之前没有上一年)进行数学计算,并且 if(length(...))
仅在存在匹配的 ID 和上一年时才执行该函数。
有什么想法吗?
您可以使用
complete()
中的 tidyr
来填充 SE441
中缺失值的所有年份 ID 组合,然后滞后应该起作用:
macro <- data.frame(ANO=c(2017,2018,2020,2018,2019,2020),
NUM_EXPLOTACION=c(657,657,657,123,123,123),
SE441=c(12,15,13,1,4,0))
library(tidyverse)
macro %>%
mutate(orig = 1) %>%
complete(ANO, NUM_EXPLOTACION, fill=list(SE441 = NA, orig=0)) %>%
arrange(NUM_EXPLOTACION, ANO) %>%
group_by(NUM_EXPLOTACION) %>%
mutate(diff = SE441-lag(SE441)) %>%
filter(orig==1)
#> # A tibble: 6 × 5
#> # Groups: NUM_EXPLOTACION [2]
#> ANO NUM_EXPLOTACION SE441 orig diff
#> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 2018 123 1 1 NA
#> 2 2019 123 4 1 3
#> 3 2020 123 0 1 -4
#> 4 2017 657 12 1 NA
#> 5 2018 657 15 1 3
#> 6 2020 657 13 1 NA
创建于 2024-05-23,使用 reprex v2.0.2