【问题标题】:Average row and it's previous row in a data.frame平均行,它是 data.frame 中的前一行
【发布时间】:2017-12-19 19:12:25
【问题描述】:

我在 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 个观察值,而且运行速度非常慢。有人对我如何编辑代码以提高效率有任何建议吗?

任何建议将不胜感激!

【问题讨论】:

标签: r performance plyr


【解决方案1】:

手动矢量化:

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

【讨论】:

    【解决方案2】:

    使用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

    【讨论】:

    • NA 不应该在前面吗?
    猜你喜欢
    • 2017-09-21
    • 1970-01-01
    • 2012-06-14
    • 2018-02-28
    • 1970-01-01
    • 2017-01-13
    • 2017-06-18
    • 2021-11-08
    相关资源
    最近更新 更多