【发布时间】: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 <- 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