平均行及其在 data.frame 中的前一行
Average row and it's previous row in a data.frame
我在 R 中编写了以下函数来计算列名为 DATE (YYYY-MM-DD)、ID、VAR1 和 VAR2 的数据帧的每个日期和前一天的两天平均 VAR。没有遗漏的日期。
df <- data.frame
TWODAY <- function(df){
df$TWODAY_VAR1 <- NA
for(j in 2:length(df$VAR1)){
df$TWODAY_VAR1[j] <- mean(df$VAR1[j:(j-1)])
}
df$TWODAY_VAR2 <- NA
for(j in 2:length(df$VAR2)){
df$TWODAY_VAR2[j] <- mean(df$VAR2[j:(j-1)])
}
return(df)
}
然后我使用 ddply 将此函数应用于我的数据框:
df <- ddply(df, "ID", TWODAY)
但是,我的数据框包含超过 13,000,000 个观察值,这 运行 非常慢。有没有人对我如何编辑代码以提高效率有任何建议?
如有任何建议,我们将不胜感激!
使用rowMeans
的解决方案:
nRow <- 13e6
df <- data.frame(VAR1 = rnorm(nRow),
VAR2 = rnorm(nRow))
df$TWODAY_VAR1 <- rowMeans(cbind(df$VAR1, c(NA, df$VAR1[-nrow(df)])))
df$TWODAY_VAR2 <- rowMeans(cbind(df$VAR2, c(NA, df$VAR2[-nrow(df)])))
cbind
两个向量 cbind(df$VAR1, c(df$VAR1[-1], NA)
(最后一行 NA
)并应用 rowMeans
.
手动矢量化:
FOO <- function(x){
c(NA, (x[2:length(x)]+x[1:(length(x)-1)])/2)
}
示例:
set.seed(123)
df <- data.frame(VAR1 = rnorm(10000), VAR2 = runif(10000))
> head(df)
VAR1 VAR2
1 -0.56047565 0.9911234
2 -0.23017749 0.3022307
3 1.55870831 0.4337590
4 0.07050839 0.1605209
5 0.12928774 0.8230267
6 1.71506499 0.2080906
df$TWODAY_VAR1 <- FOO(df$VAR1)
df$TWODAY_VAR2 <- FOO(df$VAR2)
> head(df)
VAR1 VAR2 TWODAY_VAR1 TWODAY_VAR2
1 -0.56047565 0.9911234 NA NA
2 -0.23017749 0.3022307 -0.39532657 0.6466770
3 1.55870831 0.4337590 0.66426541 0.3679948
4 0.07050839 0.1605209 0.81460835 0.2971400
5 0.12928774 0.8230267 0.09989806 0.4917738
6 1.71506499 0.2080906 0.92217636 0.5155586
即使有 1300 万行,这也应该相当快。一百万行对我来说只需要一秒钟的时间。
具有 13.000.000 行的单个变量的基准:
> b
Unit: seconds
expr min lq mean median uq max neval
df$TWODAY_VAR1 <- FOO(df$VAR1) 0.182657 0.209106 0.2308234 0.2175971 0.2239455 0.3119504 10
我在 R 中编写了以下函数来计算列名为 DATE (YYYY-MM-DD)、ID、VAR1 和 VAR2 的数据帧的每个日期和前一天的两天平均 VAR。没有遗漏的日期。
df <- data.frame
TWODAY <- function(df){
df$TWODAY_VAR1 <- NA
for(j in 2:length(df$VAR1)){
df$TWODAY_VAR1[j] <- mean(df$VAR1[j:(j-1)])
}
df$TWODAY_VAR2 <- NA
for(j in 2:length(df$VAR2)){
df$TWODAY_VAR2[j] <- mean(df$VAR2[j:(j-1)])
}
return(df)
}
然后我使用 ddply 将此函数应用于我的数据框:
df <- ddply(df, "ID", TWODAY)
但是,我的数据框包含超过 13,000,000 个观察值,这 运行 非常慢。有没有人对我如何编辑代码以提高效率有任何建议?
如有任何建议,我们将不胜感激!
使用rowMeans
的解决方案:
nRow <- 13e6
df <- data.frame(VAR1 = rnorm(nRow),
VAR2 = rnorm(nRow))
df$TWODAY_VAR1 <- rowMeans(cbind(df$VAR1, c(NA, df$VAR1[-nrow(df)])))
df$TWODAY_VAR2 <- rowMeans(cbind(df$VAR2, c(NA, df$VAR2[-nrow(df)])))
cbind
两个向量 cbind(df$VAR1, c(df$VAR1[-1], NA)
(最后一行 NA
)并应用 rowMeans
.
手动矢量化:
FOO <- function(x){
c(NA, (x[2:length(x)]+x[1:(length(x)-1)])/2)
}
示例:
set.seed(123)
df <- data.frame(VAR1 = rnorm(10000), VAR2 = runif(10000))
> head(df)
VAR1 VAR2
1 -0.56047565 0.9911234
2 -0.23017749 0.3022307
3 1.55870831 0.4337590
4 0.07050839 0.1605209
5 0.12928774 0.8230267
6 1.71506499 0.2080906
df$TWODAY_VAR1 <- FOO(df$VAR1)
df$TWODAY_VAR2 <- FOO(df$VAR2)
> head(df)
VAR1 VAR2 TWODAY_VAR1 TWODAY_VAR2
1 -0.56047565 0.9911234 NA NA
2 -0.23017749 0.3022307 -0.39532657 0.6466770
3 1.55870831 0.4337590 0.66426541 0.3679948
4 0.07050839 0.1605209 0.81460835 0.2971400
5 0.12928774 0.8230267 0.09989806 0.4917738
6 1.71506499 0.2080906 0.92217636 0.5155586
即使有 1300 万行,这也应该相当快。一百万行对我来说只需要一秒钟的时间。
具有 13.000.000 行的单个变量的基准:
> b
Unit: seconds
expr min lq mean median uq max neval
df$TWODAY_VAR1 <- FOO(df$VAR1) 0.182657 0.209106 0.2308234 0.2175971 0.2239455 0.3119504 10