我有一个包含数千个观察值的面板数据集。让我简化一下:
library(dplyr)
x1 = c(NA,NA,NA,5.1,5.0,5.4,5.15,4.9,5,6)
x2 = c(5.9,5.85,5.8,6,5.95,5.98,5.99,6.1,6.15,6.14)
df = data.frame(countrycode = c(replicate(10,"ITA"), replicate(10,"UK")),
year = c(replicate(2,2010:2019)), LogGdp = c(x1,x2))
然后,我正在寻找一种有效的方法来选择给定变量的最大值(按国家/地区代码),该方法在找到新的最大值时更新。结果应该如下面的记录栏所示
z1 = c(NA,NA,NA,5.1,5.1,5.4,5.4,5.4,5.4,6)
z2 = c(5.9,5.9,5.9,6,6,6,6,6.1,6.15,6.15)
df = data.frame(countrycode = c(replicate(10,"ITA"), replicate(10,"UK")),
year = c(replicate(2,2010:2019)), LogGdp = c(x1,x2), record = c(z1,z2))
这是我的尝试:
df %>%
group_by(countrycode) %>%
mutate(record = cummax(LogGdp))
您可以用
-Inf
替换缺失值,使用 cummax()
查找累积最大值,然后使用 -Inf
将 NA
转换回 na_if()
。
df %>%
mutate(record = replace(LogGdp, is.na(LogGdp), -Inf) %>% cummax %>% na_if(-Inf),
.by = countrycode)
# countrycode year LogGdp record
# 1 ITA 2010 NA NA
# 2 ITA 2011 NA NA
# 3 ITA 2012 NA NA
# 4 ITA 2013 5.10 5.10
# 5 ITA 2014 5.00 5.10
# 6 ITA 2015 5.40 5.40
# 7 ITA 2016 5.15 5.40
# 8 ITA 2017 4.90 5.40
# 9 ITA 2018 5.00 5.40
# 10 ITA 2019 6.00 6.00
# 11 UK 2010 5.90 5.90
# 12 UK 2011 5.85 5.90
# 13 UK 2012 5.80 5.90
# 14 UK 2013 6.00 6.00
# 15 UK 2014 5.95 6.00
# 16 UK 2015 5.98 6.00
# 17 UK 2016 5.99 6.00
# 18 UK 2017 6.10 6.10
# 19 UK 2018 6.15 6.15
# 20 UK 2019 6.14 6.15
另一种选择是
Reduce
+ pmax
。
注意: 这里必须是
pmax()
而不是 max
,因为 pmax(NA, NA, na.rm = TRUE)
按预期返回 NA
,但 max(NA, NA, na.rm = TRUE)
返回 -Inf
并带有烦人的警告消息。
df %>%
mutate(record = Reduce(\(...) pmax(..., na.rm = TRUE), LogGdp, accumulate = TRUE),
.by = countrycode)