为每个数据帧列计算每行的三个后续行数据的平均值 (R)

Computing for each datafram column the mean of three subsequent row data for each row (R)

首先,针对我的问题的简单 R 示例:

> df
   x  y
1  1  3
2  2  7
3  4  9
4  8  0
5  3  1
6 12 24

我想为每一列计算每一行的三个后续行数据的平均值,结果为以下数据框。

> dfRes
      xRes     yRes
         x        y
1 2.333333 6.333333
2 4.666667 5.333333
3 5.000000 3.333333
4 7.666667 8.333333
5       NA       NA
6       NA       NA

因为我有很多列和行的非常大的数据框,所以我想避免在这个计算中使用 for 循环。我尝试定义自定义函数以使用可用的 sapply 函数。

有人知道 R 中这个问题的计算时间相对较快的简单解决方案吗?

----更新---- 计算过程应该是这样的:

xRes[1] = mean(x[1] + x[2] + x[3])
xRes[2] = mean(x[2] + x[3] + x[4])
...
xRes[5] = NA # because there is no x[7]

地图功能怎么样? https://www.rdocumentation.org/packages/purrr/versions/0.2.5/topics/map 它实际上是 for-loop

的一个很好的替代品

我将转换矩阵中的数据框并将 colMeans 与 nrow 参数一起使用。 解决方案基本上是从这里的这个答案复制而来的:

# devtools::install_github("alistaire47/read.so")
foo <- read.so::read.so(
"
   x  y
1  1  3
2  2  7
3  4  9
4  8  0
5  3  1
6 12 24")

foo_mat <- as.matrix(foo)

sapply(foo, function(x) colMeans(matrix(x, nrow = 3)))
#>             x        y
#> [1,] 2.333333 6.333333
#> [2,] 7.666667 8.333333

这取决于长度(矩阵)是 (3) 的倍数。在另一个 post 中,我链接到一个显然处理其他情况的解决方案

您可以使用具有适当 window 大小的滚动函数。

df[] <- lapply(df, zoo::rollmean, 3, fill = NA, align = 'left')

如果您的数据量很大,使用 data.table 可能会有所帮助。

library(data.table)
setDT(df)[, lapply(.SD, frollmean, 3, align = 'left')]

this historic answer的基础上使用filter

n <- 3
df1[] <- lapply(df1, function(x) c(na.omit(filter(x, rep(1 / n, n))), rep(NA, n - 1)))
df1  
#          x        y
# 1 2.333333 6.333333
# 2 4.666667 5.333333
# 3 5.000000 3.333333
# 4 7.666667 8.333333
# 5       NA       NA
# 6       NA       NA

数据:

df1 <- structure(list(x = c(2.33333333333333, 4.66666666666667, 5, 7.66666666666667, 
NA, NA), y = c(6.33333333333333, 5.33333333333333, 3.33333333333333, 
8.33333333333333, NA, NA)), row.names = c("1", "2", "3", "4", 
"5", "6"), class = "data.frame")

使用 lagleadmutate 来自 dplyr

df%>%
mutate(x=(lag(x,0)+lead(x)+lead(x,2))/3 , y=(lag(y,0)+lead(y)+lead(y,2))/3)