我有一个下面的数据框。我想知道如何通过从'2014-1-5‘开始扩展窗口来计算'value_t’列的平均值。例如val(1)=均值(1:5),值(2)=均值(1:6),值(3)=均值(1:7)。我希望算法是高效的(无循环)。
df<-data.frame(date_t=paste('2014-01-',1:15,sep=""),value_t=1:15)
> df
date_t value_t
1 2014-01-1 1
2 2014-01-2 2
3 2014-01-3 3
4 2014-01-4 4
5 2014-01-5 5
6 2014-01-6 6
7 2014-01-7 7
8 2014-01-8 8
9 2014-01-9 9
10 2014-01-10 10
11 2014-01-11 11
12 2014-01-12 12
13 2014-01-13 13
14 2014-01-14 14
15 2014-01-15 15发布于 2014-10-09 22:30:11
那sapply(5:NROW(df), function(.) mean(df$value_t[1:.]))呢?它涉及到一种循环(sapply),但它应该是相当快的。
发布于 2014-10-10 04:39:26
sapply(...)解决方案比for(...)循环更快,但仅略快(约2% -完全在误差范围内)。事实证明,在每一步从数据帧中提取列都会大大减慢速度。如果您首先将该列作为向量获取,您将获得大约25%的改进。
df <- data.frame(value=1:1e4)
f.sapply <- function() sapply(5:nrow(df), function(.) mean(df$value[1:.]))
f.loop <- function() {result <- numeric(nrow(df)-4)
for (i in 5:nrow(df)) result[i-4] <- mean(df$value[1:i])
result
}
f.vec <- function() {vec<-df$value
sapply(5:nrow(df), function(.) mean(vec[1:.]))
}
# do they produce identical results?
identical(f.sapply(),f.loop())
# [1] TRUE
identical(f.sapply(),f.vec())
# [1] TRUE
# which is faster?
library(microbenchmark)
microbenchmark(f.sapply(),f.loop(),f.vec())
# Unit: milliseconds
# expr min lq median uq max neval
# f.sapply() 904.2934 929.7361 947.7621 978.8775 1496.455 100
# f.loop() 927.5288 950.3632 963.5926 1012.2407 1347.889 100
# f.vec() 669.5615 697.3639 711.1498 751.2634 1060.056 100发布于 2014-10-09 22:30:26
看看这个
df$val <- cumsum(df$value_t) / 1:nrow(df)
df$val[1:4] <- NA
# date_t value_t val
# 2014-01-1 1 NA
# 2014-01-2 2 NA
# 2014-01-3 3 NA
# 2014-01-4 4 NA
# 2014-01-5 5 3.0
# 2014-01-6 6 3.5
# 2014-01-7 7 4.0
# 2014-01-8 8 4.5
# 2014-01-9 9 5.0
# 2014-01-10 10 5.5
# 2014-01-11 11 6.0
# 2014-01-12 12 6.5
# 2014-01-13 13 7.0
# 2014-01-14 14 7.5
# 2014-01-15 15 8.0如果您只想要矢量,并且不想篡改df,请执行以下操作
val <- (cumsum(df$value_t) / 1:nrow(df))[-(1:4)]
# 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0https://stackoverflow.com/questions/26280637
复制相似问题