有没有其他方法可以提高R中的运行性能



我正在收集一些经济指标数据。在这个过程中,我还想用脚本收集每小时的推特计数。我以前用简单的数据问过类似的问题。随着历史数据的增长,运行时间将变得更长。由于结果表将是一个数据帧,我是否可以使用apply系列或do.call等函数更有效地运行此脚本?

library(httr)
library(dplyr)
library(lubridate)
library(tidyverse)
library(stringr)
sel1<-c('"#fed"','"#usd"','"#ecb"','"#eur"')
for (i in sel1) 
{
for (ii in 1:20){
headers = c(
`Authorization` = 'Bearer #enter your Bearer token#'
)

params = list(
`query` =i,
#my sys.time is different
`start_time` = strftime(Sys.time()-(ii+1)*60*60, "%Y-%m-%dT%H:%M:%SZ",tz ='GMT'),
`end_time` =strftime(Sys.time()-ii*60*60, "%Y-%m-%dT%H:%M:%SZ",tz ='GMT'),
`granularity` = 'hour'
)

res1<- httr::GET(url = 'https://api.twitter.com/2/tweets/counts/recent', httr::add_headers(.headers=headers), query = params) %>% 
content( as = 'parsed')
x1<-cbind(data.frame(res1),topic=str_replace_all(i, "([n"#])", ""))

if(!exists("appnd1")){
appnd1 <- x1
} else{
appnd1 <- rbind(appnd1, x1)
}
}
}

通常,在for循环中迭代rbind的数据总是会随着时间的推移而变得更糟:每次执行一个rbind,它都会将前一帧的所有帧复制到内存中,因此您拥有所有内容的两个副本。对于小数字来说,这还不错,但可以想象,在内存中复制大量数据可能会成为一个问题。(这在R Inferno,第2章,成长中的对象中有介绍。这是一本很好的读物,即使它不是最近的文档。(

最好的方法是创建一个框架列表(请参阅https://stackoverflow.com/a/24376207/3358227),将内容添加到其中,然后完成后将列表中的所有帧合并为一个帧。

未测试,但尝试此修改过程:

library(httr)
library(dplyr)
library(lubridate)
library(tidyverse)
library(stringr)
sel1<-c('"#fed"','"#usd"','"#ecb"','"#eur"')
listofframes <- list()
for (i in sel1) {
for (ii in 1:20){
headers = c(
`Authorization` = 'Bearer #enter your Bearer token#'
)

params = list(
`query` =i,
#my sys.time is different
`start_time` = strftime(Sys.time()-(ii+1)*60*60, "%Y-%m-%dT%H:%M:%SZ",tz ='GMT'),
`end_time` =strftime(Sys.time()-ii*60*60, "%Y-%m-%dT%H:%M:%SZ",tz ='GMT'),
`granularity` = 'hour'
)

res1<- httr::GET(url = 'https://api.twitter.com/2/tweets/counts/recent', httr::add_headers(.headers=headers), query = params) %>% 
content( as = 'parsed')
x1<-cbind(data.frame(res1),topic=str_replace_all(i, "([n"#])", ""))
listofframes <- c(listofframes, list(x1))
}
}
# choose one of the following based on your R-dialect/package preference
appnd1 <- do.call(rbind, listofframes)
appnd1 <- dplyr::bind_rows(listofframes)
appnd1 <- data.table::rbindlist(listofframes)

最新更新