我的数据集具有以下形式:
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
- 循环?
答案 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
为否定的情况,您可以使用0
(max((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]