找到最后4个元素的平均值

时间:2017-04-05 19:43:02

标签: r dplyr

我的数据集具有以下形式:

df<- data.frame(c("a", "a", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b"),
                c(1,    1,   1,   1,   2,   2,   2,   2,   1,   1,    1,  1,   2,    2,   2,   2),
                c(1,    2,   3,   4,   1,   2,   3,   4,   1,   2,   3 , 4,  1,    2,   3,   4),
                c(25,   75,  20,  40,  60,  50,  20,  10,  20,  30,  40,  60, 25,   75,  20,  40))
colnames(df)<-c("car", "year", "mnth", "val")

为了清楚起见,我也在这里展示:

   car year mnth val
1    a    1    1  25
2    a    1    2  75
3    a    1    3  20
4    a    1    4  40
5    a    2    1  60
6    a    2    2  50
7    a    2    3  20
8    a    2    4  10
9    b    1    1  20
10   b    1    2  30
11   b    1    3  40
12   b    1    4  60
13   b    2    1  25
14   b    2    2  75
15   b    2    3  20
16   b    2    4  40

我想向tmp添加新列df,对于特定行,tmp的值应为df$val和3的平均值先前的价值观。这里显示了tmp的一些示例

#row 3: mean(25,75,20)=40
#row 4: mean(25,75,20,40)=40
#row 5: mean(75,20,40,60)=48.75
#row 16: mean(25,75,20,40)=40

有没有一种有效的方法在R中执行此操作而不使用for - 循环?

4 个答案:

答案 0 :(得分:4)

这里使用data.table::shift

(某种程度上)矢量化解决方案
library(data.table)
colMeans(do.call(rbind, shift(df$val, 0:3)), na.rm = TRUE)
## [1] 25.00 50.00 40.00 40.00 48.75 42.50 42.50 35.00 25.00 20.00 25.00 37.50 38.75 50.00 45.00 40.00

或者@Frank建议

rowMeans(setDF(shift(df$val, 0:3)), na.rm = TRUE)

答案 1 :(得分:2)

或者只是这样

library(dplyr)
df$tmp <- (df$val+lag(df$val,1)+lag(df$val,2)+lag(df$val,3))/4

这不使用任何循环。它只是移动列表并对移位列表求和。

例如,如果您定义

a <- c(1,2,3,4,5)

然后

lag(a) 

NA  1  2  3  4

我希望它可以帮到你。

答案 2 :(得分:1)

对于每个值,计算滚动窗口的平均值,其中包括值以及前面3个值(从下面的解决方案中的索引i-3到索引i)。对于i-3为否定的情况,您可以使用0max((i-3),0)

sapply(seq_along(df$val), function(i)
      mean(df$val[max((i-3),0):i], na.rm = TRUE))
#[1] 25.00 50.00 40.00 40.00 48.75 42.50 42.50 35.00 25.00
#[10] 20.00 25.00 37.50 38.75 50.00 45.00 40.00

另请考虑rollmean

zoo
library(zoo)
c(rep(NA,3), rollmean(x = df$val, k = 4))
#[1]    NA    NA    NA 40.00 48.75 42.50 42.50 35.00 25.00 20.00 25.00
#[12] 37.50 38.75 50.00 45.00 40.00
#FURTHER TWEAKING MAY BE NECESSARY

答案 3 :(得分:1)

您也可以使用data.table

library(data.table)

setDT(df)
df[, tmp := (val + shift(val,1,type="lag") + shift(val,2,type="lag") + shift(val,3,type="lag"))/4]