ddply 时间和性能问题
ddply timing and performance issue
我需要一些帮助来剖析 ddply 计时问题的根源。 ddply 函数在小型数据集(~4MB 数据帧)上需要 10 分钟以上才能 运行。
我正尝试通过以下方式 运行 ddply:
new_df<- ddply(old_df, .(TIC), mutate, mean_price_3yr=rollmean(price, k=3, align= "right",na.pad=T))
old_df 的形式为:
fyear TIC ebitda price
1 2000 AIR 64.367 14.00
2 2001 AIR 27.207 11.44
3 2002 AIR 30.745 4.50
4 2003 AIR 47.491 9.58
...
fyear TIC ebitda price
21 2005 ADCT 159.000 17.450
22 2006 ADCT 140.400 14.310
23 2007 ADCT 167.900 18.700
24 2008 ADCT 173.300 6.340
25 2009 ADCT 84.700 8.340
26 2010 ADCT 121.400 12.670
27 2000 ALO.2 190.533 43.875
28 2001 ALO.2 163.601 26.450
29 2002 ALO.2 187.264 11.910
30 2003 ALO.2 155.228 20.100
31 2004 ALO.2 153.829 16.950
...
我的 ddply 的目的是计算按 TIC 分组的最后 3 个周期的价格滚动平均值。我确保在 运行 编写代码之前至少对 TIC 进行了 3 次观察。总共 80,000 行中有约 10,000 个唯一 TIC。
在另一篇文章的帮助下,我能够重用 ave 函数来完成我的任务:
old_df$last3<-ave(old_df$price, old_df$TIC, FUN=function(x) rollmean(x, k=3, align= "right",na.pad=T))
运行这段代码耗时约1秒,圆满完成任务。
我运行正在使用 Macbook Pro,16GB RAM,2.8GHz Intel Core i7。如果有人可以帮助我诊断问题,将不胜感激!
Update1:这里是实际应用中运行次的对比。我没有包含 ddply 结果,因为我不想等那么久 :P
> system.time(test<-epdata %>% group_by(LPERMNO) %>% mutate(mean_price_3yr = roll_mean(ebitda, n=3, align="right", fill=NA)))
user system elapsed
0.570 0.007 0.577
> system.time(epdata_2$delta_earnings<-ave(epdata_2$ebitda, epdata_2$LPERMNO, FUN=function(x) Delt(x, k=1, type = "arithmetic")))
user system elapsed
2.583 0.007 2.600
我们可以通过使用 library(RcppRoll)
中的 roll_mean
和 dplyr
来提高效率
library(RcppRoll)
library(dplyr)
old_df %>%
group_by(TIC) %>%
mutate(mean_price_3yr = roll_mean(price, n=3,
align="right", fill=NA))
数据
old_df <- structure(list(fyear = c(2000L, 2001L, 2002L,
2003L, 2005L, 2006L,
2007L, 2008L, 2009L, 2010L, 2000L, 2001L, 2002L, 2003L,
2004L), TIC = c("AIR", "AIR", "AIR", "AIR", "ADCT",
"ADCT", "ADCT",
"ADCT", "ADCT", "ADCT", "ALO.2", "ALO.2", "ALO.2",
"ALO.2", "ALO.2"
), ebitda = c(64.367, 27.207, 30.745, 47.491, 159, 140.4,
167.9, 173.3, 84.7, 121.4, 190.533, 163.601, 187.264,
155.228, 153.829), price = c(14, 11.44, 4.5, 9.58, 17.45,
14.31, 18.7, 6.34, 8.34, 12.67, 43.875, 26.45, 11.91,
20.1, 16.95)), .Names = c("fyear", "TIC", "ebitda",
"price"), class = "data.frame", row.names = c(NA, -15L))
我需要一些帮助来剖析 ddply 计时问题的根源。 ddply 函数在小型数据集(~4MB 数据帧)上需要 10 分钟以上才能 运行。
我正尝试通过以下方式 运行 ddply:
new_df<- ddply(old_df, .(TIC), mutate, mean_price_3yr=rollmean(price, k=3, align= "right",na.pad=T))
old_df 的形式为:
fyear TIC ebitda price
1 2000 AIR 64.367 14.00
2 2001 AIR 27.207 11.44
3 2002 AIR 30.745 4.50
4 2003 AIR 47.491 9.58
...
fyear TIC ebitda price
21 2005 ADCT 159.000 17.450
22 2006 ADCT 140.400 14.310
23 2007 ADCT 167.900 18.700
24 2008 ADCT 173.300 6.340
25 2009 ADCT 84.700 8.340
26 2010 ADCT 121.400 12.670
27 2000 ALO.2 190.533 43.875
28 2001 ALO.2 163.601 26.450
29 2002 ALO.2 187.264 11.910
30 2003 ALO.2 155.228 20.100
31 2004 ALO.2 153.829 16.950
...
我的 ddply 的目的是计算按 TIC 分组的最后 3 个周期的价格滚动平均值。我确保在 运行 编写代码之前至少对 TIC 进行了 3 次观察。总共 80,000 行中有约 10,000 个唯一 TIC。
在另一篇文章的帮助下,我能够重用 ave 函数来完成我的任务:
old_df$last3<-ave(old_df$price, old_df$TIC, FUN=function(x) rollmean(x, k=3, align= "right",na.pad=T))
运行这段代码耗时约1秒,圆满完成任务。
我运行正在使用 Macbook Pro,16GB RAM,2.8GHz Intel Core i7。如果有人可以帮助我诊断问题,将不胜感激!
Update1:这里是实际应用中运行次的对比。我没有包含 ddply 结果,因为我不想等那么久 :P
> system.time(test<-epdata %>% group_by(LPERMNO) %>% mutate(mean_price_3yr = roll_mean(ebitda, n=3, align="right", fill=NA)))
user system elapsed
0.570 0.007 0.577
> system.time(epdata_2$delta_earnings<-ave(epdata_2$ebitda, epdata_2$LPERMNO, FUN=function(x) Delt(x, k=1, type = "arithmetic")))
user system elapsed
2.583 0.007 2.600
我们可以通过使用 library(RcppRoll)
中的 roll_mean
和 dplyr
library(RcppRoll)
library(dplyr)
old_df %>%
group_by(TIC) %>%
mutate(mean_price_3yr = roll_mean(price, n=3,
align="right", fill=NA))
数据
old_df <- structure(list(fyear = c(2000L, 2001L, 2002L,
2003L, 2005L, 2006L,
2007L, 2008L, 2009L, 2010L, 2000L, 2001L, 2002L, 2003L,
2004L), TIC = c("AIR", "AIR", "AIR", "AIR", "ADCT",
"ADCT", "ADCT",
"ADCT", "ADCT", "ADCT", "ALO.2", "ALO.2", "ALO.2",
"ALO.2", "ALO.2"
), ebitda = c(64.367, 27.207, 30.745, 47.491, 159, 140.4,
167.9, 173.3, 84.7, 121.4, 190.533, 163.601, 187.264,
155.228, 153.829), price = c(14, 11.44, 4.5, 9.58, 17.45,
14.31, 18.7, 6.34, 8.34, 12.67, 43.875, 26.45, 11.91,
20.1, 16.95)), .Names = c("fyear", "TIC", "ebitda",
"price"), class = "data.frame", row.names = c(NA, -15L))