【问题标题】:Carry observations forward based on increasing values by group基于按组递增的值进行观察
【发布时间】:2019-11-28 18:02:15
【问题描述】:

我想我有一个简单的问题,但我正在寻找更有效(就所需计算能力而言)的方法来执行以下操作。 我有一个包含数千列的数据集,我只想为它们中的每一个 locf (结转最后一次观察)。 我需要尊重的唯一条件是最高值结转

我的数据看起来像这样

df <- data.frame("ID" = c("Alpha", "Alpha", "Alpha", "Alpha", "Alpha", "Beta", "Beta", "Beta", "Beta", "Beta"), "Year" = c(1970, 1980, 1990, 2000, 2010, 1970, 1980, 1990, 2000, 2010), "Var" = c(NA, NA, 0, NA, NA, NA, 1, NA, 2, NA), "otherVar" = c(NA, 2.34, 1.3, NA, NA, 1.3, NA, 3.5, 1.5, NA))
df
#>       ID Year Var otherVar
#> 1  Alpha 1970  NA       NA
#> 2  Alpha 1980  NA     2.34
#> 3  Alpha 1990   0     1.30
#> 4  Alpha 2000  NA       NA
#> 5  Alpha 2010  NA       NA
#> 6   Beta 1970  NA     1.30
#> 7   Beta 1980   1       NA
#> 8   Beta 1990  NA     3.50
#> 9   Beta 2000   2     1.50
#> 10  Beta 2010  NA       NA

我想获取以下数据

final <- data.frame("ID" = c("Alpha", "Alpha", "Alpha", "Alpha", "Alpha", "Beta", "Beta", "Beta", "Beta", "Beta"), "Year" = c(1970, 1980, 1990, 2000, 2010, 1970, 1980, 1990, 2000, 2010), "Var" = c(NA, NA, 0, 0, 0, NA, 1, 1, 2, 2), "otherVar" = c(NA, 2.34, 2.34, 2.34, 2.34, 1.3, 1.3, 3.5, 3.5, 3.5))
final
#>       ID Year Var otherVar
#> 1  Alpha 1970  NA       NA
#> 2  Alpha 1980  NA     2.34
#> 3  Alpha 1990   0     2.34
#> 4  Alpha 2000   0     2.34
#> 5  Alpha 2010   0     2.34
#> 6   Beta 1970  NA     1.30
#> 7   Beta 1980   1     1.30
#> 8   Beta 1990   1     3.50
#> 9   Beta 2000   2     3.50
#> 10  Beta 2010   2     3.50

正如我所提到的,我的想法是,对于我的每个变量,我想用最后的观察结果来填充 NA。但我只想保留最高价值。例如 otherVar 在 1970 年是 1.3,所以这个值被结转到 1980 年以填补 NA。在 1990 年,otherVar 的值为 3.5,因此它“取代”了 1.3,而 1990 年otherVar 的得分为 3.5。最后,在 2000 年,otherVar 的得分为 1.5。由于 1.5

我想找到计算量最少的方法来执行此操作,因为我必须为数千个变量执行此操作。

非常感谢您的帮助

最好的问候

【问题讨论】:

  • 听起来像cummax。

标签: r


【解决方案1】:

我们可以在replace使用 0 的 NA 之后使用 cummax,然后将 0 改回 NA

library(dplyr)
library(tidyr)
df %>% 
   group_by(ID) %>% 
   mutate_at(3:4,  ~ na_if(cummax(replace_na(., -999)), -999))

【讨论】:

  • 很好的解决方案。- 至少我第一眼就想到了。但它并不能完全满足 OP 请求 - 看看组 Beta 中会发生什么
  • 我正在尝试这个解决方案,但它似乎并不完美。显然它只是将var 和othervar 分数更改为每个ID 的最大值。而不是继续观察
  • @Alex 由于性能很重要,将这个答案翻译成data.table 可能是值得采取的额外步骤。
  • @Alex 您可以使用data.table set 方法更改值或尝试setDT(df)[, (3:4) := lapply(.SD, function(x) cummax(replace(x, is.na(x), 0))), ID, .SDcols = 3:4]
  • 感谢这太棒了@Akrun
猜你喜欢
  • 1970-01-01
  • 2016-07-04
  • 2019-03-07
  • 1970-01-01
  • 2021-09-25
  • 2021-12-16
  • 1970-01-01
  • 2021-05-08
  • 2017-06-29
相关资源
最近更新 更多