簡體   English   中英

如果在R中使用嵌套優化For循環

[英]Optimizing For loop with nested if in R

我正在嘗試將多個csv文件合並到單個數據框中,並嘗試使用for循環來操縱結果數據框。 結果數據幀可能有1,500,000至2,000,000行之間的任意位置。

我使用下面的代碼相同。

setwd("D:/Projects")
library(dplyr)
library(readr)
merge_data = function(path) 
{ 
  files = dir(path, pattern = '\\.csv', full.names = TRUE)
  tables = lapply(files, read_csv)
  do.call(rbind, tables)
}


Data = merge_data("D:/Projects")
Data1 = cbind(Data[,c(8,9,17)],Category = "",stringsAsFactors=FALSE)
head(Data1)

for (i in 1:nrow(Data1))
{ 
  Data1$Category[i] = ""
  Data1$Category[i] = ifelse(Data1$Days[i] <= 30, "<30",
                       ifelse(Data1$Days[i] <= 60, "31-60",
                       ifelse(Data1$Days[i] <= 90, "61-90",">90")))     

}

但是,代碼運行了很長時間。 有沒有更好,更快的方法來執行相同的操作?

通過從data.table讀取fread ,然后使用cut/findInterval可以使此操作更加優化。 當它在服務器上的多個內核中運行時, fread將利用所有節點並並行執行,這將變得更加明顯。

library(data.table)
merge_data <- function(path) { 
   files = dir(path, pattern = '\\.csv', full.names = TRUE)
  rbindlist(lapply(files, fread, select = c(8, 9, 17)))
 }

Data <- merge_data("D:/Projects")
Data[, Category := cut(Data1, breaks = c(-Inf, 30, 60, 90, Inf), 
      labels = c("<=30", "31-60", "61-90", ">90"))]

您已經在使用dplyr ,為什么不這樣做:

Data = merge_data("D:/Projects") %>%
  select(8, 9, 17) %>%
  mutate(Category = cut(Days,
                        breaks = c(-Inf, 30, 60, 90, Inf), 
                        labels = c("<=30", "31-60", "61-90", ">90"))

Akrun確實正確,因為fread的讀取速度要快得多。

但是,除了他的文章外,我還要補充一點,您的for循環完全沒有必要。 他用不熟悉的cut / findInterval代替了它。 但是,就簡單的R編程而言,當計算中的某些因素逐行更改時,for循環是必需的。 但是,在您的代碼中並非如此,並且不需要for循環。

本質上,當您只需要對該列運行一次時,您最多可以運行200萬次計算。

您可以使用以下內容替換您的for循環:

Data1$category = ifelse(Data1$Days <= 30, "<=30",
                 ifelse(Data1$Days <= 60, "31-60",
                 ifelse(Data1$Days <= 90, "61-90",">90")))

而且您的代碼將更快地運行waaaaaay

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM