在数据子集上应用函数的最有效方法(ddply 的替代方法)
Most efficient way to apply function on the subset of data (alternatives to ddply)
我有相当多的数据集,其中随时间报告不同对象的值。此外,价值本身可以每年多次衡量。我只对 对给定年份的一个对象的估值 取简单平均值感兴趣。我的问题是,由于数据的大小,在选定的子集上应用函数需要相当长的时间。有没有更有效的方法来做到这一点?我在某处读到,使用 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,因为还有其他特征稍后会在分析中使用。
正如 Imo 和 user3293236 在评论中指出的那样,使用 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)]
dplyr
与data.table
的比较
mean(time_taken_df)
[1] 1.357766
mean(time_taken_dt)
[1] 0.003700418
我有相当多的数据集,其中随时间报告不同对象的值。此外,价值本身可以每年多次衡量。我只对 对给定年份的一个对象的估值 取简单平均值感兴趣。我的问题是,由于数据的大小,在选定的子集上应用函数需要相当长的时间。有没有更有效的方法来做到这一点?我在某处读到,使用 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,因为还有其他特征稍后会在分析中使用。
正如 Imo 和 user3293236 在评论中指出的那样,使用 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)]
dplyr
与data.table
mean(time_taken_df)
[1] 1.357766
mean(time_taken_dt)
[1] 0.003700418