计算R data.table中前三行的总和(按网格方)

thr*_*les 4 r filter zoo data.table

我想计算每个网格方块过去三天的降雨量,并将其添加为我的data.table中的新列.为了清楚起见,我想总结一下当前和上一天的降雨量,对于每个气象网格广场

library ( zoo )
library (data.table)


# making the data.table
rain           <- c(NA, NA, NA, 0, 0, 5, 1, 0, 3, 10)  # rainfall values to work with
square         <- c(1,1,1,1,1,1,1,1,1,2)               # the geographic grid square for the rainfall measurement
desired_result <- c(NA, NA, NA, NA, NA, 5, 6, 6, 4, NA )  # this is the result I'm looking for (the last NA as we are now on to the first day of the second grid square)
weather <- data.table(rain, square, desired_result)  # making the data.table
Run Code Online (Sandbox Code Playgroud)

我试图回答:这条线曾经工作,但不再适用

weather[, rain_3 := filter(rain, rep(1, 2), sides = 1), by = list(square)]  
Run Code Online (Sandbox Code Playgroud)

所以我在这里尝试另一种方法:

# this next line gets the numbers right, but sums the following values, not the preceeding ones. 
weather$rain_3 <- rollapply(zoo(weather$rain), list(seq(-2,0)), sum)

# here I add in the by weather$ square, but still no success
weather$rain_3 <- rollapply(zoo(weather$rain), list(seq(-2,0)), sum, by= list(weather$square))
Run Code Online (Sandbox Code Playgroud)

我非常感谢您的任何见解或建议.

非常感谢!

Dav*_*urg 21

这是使用最新data.table版本(v 1.9.6+)的快速有效的解决方案

weather[, rain_3 := Reduce(`+`, shift(rain, 0:2)), by = square]
weather
#     rain square desired_result rain_3
#  1:   NA      1             NA     NA
#  2:   NA      1             NA     NA
#  3:   NA      1             NA     NA
#  4:    0      1             NA     NA
#  5:    0      1             NA     NA
#  6:    5      1              5      5
#  7:    1      1              6      6
#  8:    0      1              6      6
#  9:    3      1              4      4
# 10:   10      2             NA     NA
Run Code Online (Sandbox Code Playgroud)

这里的基本思想是shiftrain柱两次,然后总结行.


Rol*_*and 2

weather[, rain_3 := filter(rain, rep(1, 3), sides = 1), by = list(square)]  
#Error in filter(rain, rep(1, 3), sides = 1) : 
#  'filter' is longer than time series
weather[, rain_3 := if(.N > 2) filter(rain, rep(1, 3), sides = 1) else NA_real_, 
        by = square] 
#    rain square desired_result rain_3
# 1:   NA      1             NA     NA
# 2:   NA      1             NA     NA
# 3:   NA      1             NA     NA
# 4:    0      1             NA     NA
# 5:    0      1             NA     NA
# 6:    5      1              5      5
# 7:    1      1              6      6
# 8:    0      1              6      6
# 9:    3      1              4      4
#10:   10      2             NA     NA
Run Code Online (Sandbox Code Playgroud)

请注意 dplyr 未加载,因为它会屏蔽filter。如果需要 dplyr,可以stats::filter显式调用。