如何在R中加速此循环
我有下面的代码,它读取表的列,如果元素包含正确的字符串,它会在另一个向量中增加相应的值。代码如下:如何在R中加速此循环,r,R,我有下面的代码,它读取表的列,如果元素包含正确的字符串,它会在另一个向量中增加相应的值。代码如下: dateArray <- integer(365) for (i in 189500:207097) { if (grepl("Jan", csvaryana[i, "Date"], ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE)) { for (j in 1:31) {
dateArray <- integer(365)
for (i in 189500:207097) {
if (grepl("Jan", csvaryana[i, "Date"], ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE)) {
for (j in 1:31) {
if (j < 10) {
if (grepl(paste(sprintf(" 0%d", j), ""), csvaryana[i, "Date"], ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE))
dateArray[j] <- dateArray[j] + 1
}
if (grepl(paste(sprintf(" %d", j), ""), csvaryana[i, "Date"], ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE))
dateArray[j] <- dateArray[j] + 1
}
}
}
dateArray
dateArray不要对
循环使用,就是这样。有一个非常好的SO帖子讨论了这一点:
答案是要用数据框来加速进程(通过<代码>应用程序>代码>家庭或结帐>代码> PURRR <代码>。清理数据和代码,这样代码> SCAFTF(“0% D”,J)< /代码>不在循环中计算,考虑替换<代码> GRPL < /代码>。
一篇讨论这些概念的好博客文章:
对于
在R中的循环,正如其他答案所解释的那样,速度非常慢。
如果您想加快循环速度,可以阅读本文:
根据本文,您可以执行以下步骤:
使用ifesle
而不是if
获取检查循环外部条件(if语句)的语句
仅在真实条件下运行循环
使用which()
使用apply函数族而不是for循环
如果您有多核机器,请使用并行处理
使用消耗更少内存的数据结构
<> LI>如果你知道C++,那么最好的方法是使用RCPP,它运行C++代码。
如果没有一个运行的示例,这是很难做到的。您可以从将循环的每个元素都变成一个函数开始。让我们按如下方式对行进行编号:
#1 for (i in 189500:207097) {
#2 if (grepl("Jan", csvaryana[i, "Date"], ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE)) {
#3 for (j in 1:31) {
#4 if (j < 10) {
#5 if (grepl(paste(sprintf(" 0%d", j), ""), csvaryana[i, "Date"], ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE))
#6 dateArray[j] <- dateArray[j] + 1
#7 }
#8 if (grepl(paste(sprintf(" %d", j), ""), csvaryana[i, "Date"], ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE))
#9 dateArray[j] <- dateArray[j] + 1
#10 }
#11 }
#12 }
因此,此函数将在函数外部更新dateArray
(无需返回)。我们可以将相同的原理应用于更大的循环(i
):
##检查一月(第2行至第11行)
check.jan我没有循环就解决了这个问题。我将日期列分为年、月、日和时间,所以我只调用count(月和日),它返回一个向量,其中包含每个月和日的频率:
dateVector <- count(outfile, "X2")
dateVector请给出一个数据的小例子,我们需要看看Date
是如何格式化的。这可能要快得多。很可能会快得多,但除非我们了解数据,否则我们无法给出最佳建议。dateArray[as.numeric(format)(strtime)(grep(“Jan”),csvaryana[,,“Date”]、T、value=T)、“%b%d”)、“%d”)]=1
甚至dataArray[as.numeric(gsub(\\d),grep(“Jan”,csvaryana$Date,T,value=T))]=1
dateArray[as.numeric(gsub(\\d“,”,grep(“Jan”,csvaryana$Date,T,value=T))]=1
I gues这里应该没有for循环。您可以尝试上面的方法。原始代码似乎只计算1月份每个日期的实例-因此最快和最简单的解决方案可能是将日期列转换为适当的date
数据类型,并使用现有的日期工具(可能使用lubridate
).像这样手动操作太复杂了。
## Update dateArray function (lines 4 to 10)
update.dateArray <- function(j, i, dateArray, csvaryana) {
if (j < 10) {
if (grepl.ifelse(paste(sprintf(" 0%d", j), ""), i, csvaryana)) {
dateArray[j] <<- dateArray[j] + 1
}
} else {
if (grepl.ifelse(paste(sprintf(" %d", j), ""), i, csvaryana)){
dateArray[j] <<- dateArray[j] + 1
}
}
}
## Checking the month of January (lines 2 to 11)
check.jan <- function(i, dateArray, csvaryana) {
if(grepl.ifelse("Jan", i, csvaryana)) {
## Update dateArray out of the function
dateArray <<- sapply(1:31, update.dateArray, i, dateArray, csvaryana)
}
return(dateArray)
}
dateArray <- integer(365)
## Running the whole loop
sapply(189500:207097, check.jan, dateArray, csvaryana)
## Updated dateArray
dateArray
dateVector <- count(outfile, "X2")