多窗口范围计算数据表与dplyr
我在多个窗口对股票回报进行范围计算(即最大值和最小值)。 我的版本是dplyr,但许多人发布基准测试,其中使用data.table进行计算的速度要快得多。我用data.table语法创建了这个版本,但是它比dplyr版本慢。 有谁能帮我找到更好的方法来使用data.table使其更快? 非常感谢多窗口范围计算数据表与dplyr,r,data.table,dplyr,R,Data.table,Dplyr,我在多个窗口对股票回报进行范围计算(即最大值和最小值)。 我的版本是dplyr,但许多人发布基准测试,其中使用data.table进行计算的速度要快得多。我用data.table语法创建了这个版本,但是它比dplyr版本慢。 有谁能帮我找到更好的方法来使用data.table使其更快? 非常感谢 library(Quandl) library(tidyr) library(dplyr) library(data.table) library(microbenchmark) tickers &l
library(Quandl)
library(tidyr)
library(dplyr)
library(data.table)
library(microbenchmark)
tickers <- c("GOOG/NASDAQ_AAPL", "GOOG/NASDAQ_MSFT",
"GOOG/NYSE_IBM", "GOOG/NASDAQ_GOOG")
data <- Quandl(tickers,transformation = "rdiff")
returns <- gather(data, stock, value, -Date) %>%
separate(stock, c("name", "field"), " - ") %>%
filter(
field == "Close"
) %>%
select(
- field
)
returns_dt <- data.table(returns)
multi_window_range <- function(data) {
result_1y <- data %>%
filter(
Date >= Sys.Date() - 365
) %>%
group_by(name) %>%
summarise(
max_1y = max(value, na.rm = TRUE),
min_1y = min(value, na.rm = TRUE)
)
result_2y <- data %>%
filter(
Date >= Sys.Date() - 365 * 2
) %>%
group_by(name) %>%
summarise(
max_2y = max(value, na.rm = TRUE),
min_2y = min(value, na.rm = TRUE)
)
result_5y <- data %>%
filter(
Date >= Sys.Date() - 365 * 5
) %>%
group_by(name) %>%
summarise(
max_5y = max(value, na.rm = TRUE),
min_5y = min(value, na.rm = TRUE)
)
return(inner_join(inner_join(result_1y, result_2y, by = "name"), result_5y, by = "name"))
}
multi_window_range_dt <- function(data) {
setkey(data, name)
result_1y <- data[Date >= Sys.Date() - 365,
list(
max_1y = max(value, na.rm = TRUE),
min_1y = min(value, na.rm = TRUE)
), by = "name"]
result_2y <- data[Date >= Sys.Date() - 365 * 2,
list(
max_2y = max(value, na.rm = TRUE),
min_2y = min(value, na.rm = TRUE)
), by = "name"]
result_5y <- data[Date >= Sys.Date() - 365 * 5,
list(
max_5y = max(value, na.rm = TRUE),
min_5y = min(value, na.rm = TRUE)
), by = "name"]
return(result_1y[result_2y][result_5y])
}
microbenchmark(
multi_window_range(returns),
multi_window_range_dt(returns_dt)
)
Unit: milliseconds
expr min lq mean median uq max neval
multi_window_range(returns) 6.341532 6.522303 6.915266 6.692666 6.922623 10.16709 100
multi_window_range_dt(returns_dt) 7.537073 7.738516 8.066579 7.865968 8.073114 12.68021 100
库(Quandl)
图书馆(tidyr)
图书馆(dplyr)
库(数据表)
图书馆(微基准)
股票代码%
挑选(
-场
)
回报率_dt%
分组单位(名称)%>%
总结(
max_1y=max(值,na.rm=TRUE),
min_1y=min(值,na.rm=TRUE)
)
结果Y%
滤器(
日期>=系统日期()-365*2
) %>%
分组单位(名称)%>%
总结(
max_2y=max(值,na.rm=TRUE),
min_2y=min(值,na.rm=TRUE)
)
结果5y%
滤器(
日期>=系统日期()-365*5
) %>%
分组单位(名称)%>%
总结(
max_5y=max(值,na.rm=真),
min_5y=min(值,na.rm=TRUE)
)
return(内部联接(内部联接(result\u 1y,result\u 2y,by=“name”)、result\u 5y,by=“name”))
}
多窗口范围尝试以下方法:
multi_window_range_dt2 <- function(data) {
data[, {
rng1 <- range(value[Date > Sys.Date() - 365], na.rm = TRUE)
rng2 <- range(value[Date > Sys.Date() - 2*365], na.rm = TRUE)
rng5 <- range(value[Date > Sys.Date() - 5*365], na.rm = TRUE)
list(max_1y = rng1[2], min_1y = rng1[1],
max_2y = rng2[2], min_2y = rng2[1],
max_5y = rng5[2], min_5y = rng5[1])
}, by = "name"]
}
library(rbenchmark)
benchmark(multi_window_range(returns), multi_window_range_dt2(returns_dt))[1:4]
这表明multi\u window\u range
比multi\u window\u range\u dt2
花费的时间多18.9%:这里的主要优势似乎是使用范围,而不是分别使用最小值和最大值。无论如何,这是一个好主意。这可能也是由于在最后消除了连接。啊,是的,在这个问题中,通过拆分by=“name”
仅一次而不是三次来节省。公平的比较也只能与dplyr
分组进行一次。是的,如果目的是比较dplyr和data.table,这不是一个公平的比较,因为我们也可以将这些想法应用到dplyr,但问题是如何加速data.table代码。是的,但你可以这样做:`data%>%filter(日期>系统日期()-5*365,!is.na(值))%%>%group_by(name)%%>%summary(max_1y=max(value[Date>Sys.Date()-365]),min_1y=min(value[Date>Sys.Date()-365]),max_2y=max(value[Date>Sys.Date()-2*365]),min_2y=min(value[Date>Sys Date()-2*365]),max_5y=max(value),min(value))`
test replications elapsed relative
1 multi_window_range(returns) 100 2.39 1.189
2 multi_window_range_dt2(returns_dt) 100 2.01 1.000