【问题标题】:Most efficient way to apply function on the subset of data (alternatives to ddply)在数据子集上应用函数的最有效方法(ddply 的替代方案)
【发布时间】:2018-01-19 21:15:23
【问题描述】:

我有相当大量的数据集,其中随着时间的推移报告了不同对象的值。此外,每年可以多次测量价值本身。我只是对在给定年份中对一个对象获取平均估值感兴趣。我的问题是,由于数据的大小,在选定的子集上应用函数需要相当长的时间。有没有更有效的方法来做到这一点?我在某处读到使用data.table 应该加快这个过程,但我的玩具示例并非如此。

玩具示例(+ 基准测试):

library(data.table)
library(dplyr)

time_taken_df = c()
time_taken_dt = c()

test_data <- data.frame(id = round(runif(1000, 1,10), 0),
                        Value = round(runif(1000, 10, 50), 0),
                        Value_Year = round(runif(1000, 1999, 2010), 0))

for (i in 1:100){

  #Data Frame
  test_data <- as.data.frame(test_data)

  start_time_df <- Sys.time()

  test_data <- test_data %>%
    ddply(.(id, Value_Year), mutate, new_val = mean(Value))

  end_time_df <- Sys.time()

  #Data Table
  test_data <- as.data.table(test_data)

  start_time_dt <- Sys.time()

  test_data <- test_data %>%
    ddply(.(id, Value_Year), mutate, new_val = mean(Value))

  end_time_dt <- Sys.time()

  #Results
  time_taken_df[i] <- end_time_df - start_time_df
  time_taken_dt[i] <- end_time_dt - start_time_dt
}


mean(time_taken_df)
mean(time_taken_dt)

欢迎任何关于如何实现更快性能的建议!

注意:

  • 我将实际估值日期缩短为估值年份,以提高示例的清晰度。

  • 所需的输出是 data.frame,因为还有其他特征稍后会在分析中使用。

【问题讨论】:

  • 您没有使用data.table 进行分组并取平均值,您只是在data.table 上使用plyr::ddply(),这不会提高性能。
  • 需要使用data.table语法:test_data &lt;- data.table(id = round(runif(1000, 1,10), 0), Value = round(runif(1000, 10, 50), 0), Value_Year = round(runif(1000, 1999, 2010), 0)) test_data[,mean(Value), by=c("id", "Value_Year")]
  • 公平点,我会尝试解决这个问题并比较结果!
  • 或者,如果您想将平均值添加到数据集中,而不进行聚合,您可以使用setDT(test_data)[, myAvg := mean(Value), by=.(id, Value_Year)]
  • 我不知道setDT 函数,看起来很整洁。谢谢大家的建议。

标签: r dataframe datatable dplyr plyr


【解决方案1】:

正如 Imouser3293236 在 cmets 中指出的,使用 data.table 可以显着提高性能。使用:

setDT(test_data)[, myAvg := mean(Value), by=.(id, Value_Year)]

或者如果test_data 已经是data.table

data_table %>%
    [, myAvg := mean(Value), by=.(id, Value_Year)]

dplyrdata.table 之间的比较

mean(time_taken_df)
[1] 1.357766 

mean(time_taken_dt) 
[1] 0.003700418

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    • 2014-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多