簡體   English   中英

對數據幀中的數據進行分類並保存在 R 中的最有效和最快的方法

[英]The most efficient and fastest way to categorise data in dataframes and save in R

我有 1000 個數據幀從 1000 個不同的 txt 文件導入,如下所示。

Surname Name   Type Age Dept
Gold    Craige  1   24  100
Goodwin Madison 1   41  49
Young   Emma    2   31  34
Young   Rose    2   26  3
Young   Brad    2   42  76
Young   Kim     2   30  100
Smith   Emma    2   18  50
Smith   Kim     2   21  70
Hacksaw Ben     2   33  88
Hacksaw Richard 2   28  77
Hacksaw Charles 2   49  250

根據Type列,每個df需要按如下方式進行分類和保存:如果Type=1,則將相關行保存到一個單獨的xlsx文件中,命名為Surename。

如果 Type=2,則在 A 列中創建一個命名為姓氏的文件夾,並根據 B 列為每個名稱保存單獨的 xlsx 文件。

我目前所做的是對每種類型使用 split 函數,並為類型 1 放置一個循環,為類型 2 放置一個嵌套循環來創建姓氏文件夾和個人名稱 xlsx 文件,如下所示,這非常耗時(完成時間超過 13 小時) )。 半代碼如下。

for (i in 1:lenght(file_names))

rawdata <- read the data frame [i]


TYPE1 <- rawdata %>% filter(TYPE == "1") 
TYPE2 <- rawdata %>% filter(TYPE == "2") 

Split.TYPE1 <- split(TYPE1, TYPE1$Surname) 
Split.TYPE2 <- split(TYPE2, TYPE2$Surname) 


#--------------------------------- Save the TYPE 1 reports---------------------------------------
for (nm in names(Split.TYPE1)){
  file<-paste0(nm,".xlsx")
  d1<-as.data.frame(Split.TYPE1[[nm]])

  wb<-createWorkbook(file)
  addWorksheet(wb, "test", gridLines = T)
  writeData(wb, sheet = "test", x = d1)
  saveWorkbook(wb, file, overwrite = TRUE)
}

# #------------------------------ Save the TYPE 2 in a folder ----------------------------------
for (dn in names(Split.TYPE2)){
   dnn <- paste0(dn)
  dir.create(dnn)
  sub_Split.TYPE2 <- split(Split.TYPE2[[dn]], Split.TYPE2[[dn]]$Name)
  for (fn in names(sub_Split.TYPE2)){
    file<-file.path(dnn, paste0(fn,".xlsx"))

    d1<-as.data.frame(sub_Split.TYPE2[[fn]])

wb<-createWorkbook(file)
    addWorksheet(wb, "test", gridLines = T)
    writeData(wb, sheet = "test", x = d1)
    saveWorkbook(wb, file, overwrite = TRUE)
  }}
gc()
}

我只是想知道是否有更快、更優化的方法來使用更少的循環生成相同的輸出。 應用並行(foreach 包)計算並沒有加快多少。

謝謝。

這是一個關於如何將最后一個嵌套循環轉換為對 lapply 的調用的示例。

system.time({
    for (dn in names(Split.TYPE2)){
        dnn <- paste0(dn)
        ## do something with dnn
        sub_Split.TYPE2 <- split(Split.TYPE2[[dn]], Split.TYPE2[[dn]]$Name)
        for (fn in names(sub_Split.TYPE2)){
            d1<-as.data.frame(sub_Split.TYPE2[[fn]])
            ## do something with d1
        }
    }
})

system.time({
    lapply(Split.TYPE2, function(spl) {
        dnn = spl$Surname[1]
        ## do something with dnn
        sub_Split.TYPE2 = split(spl, spl$Name)
        lapply(sub_Split.TYPE2, function(d1) {
            ## do something with d1
        })
    })
})

替代方法,對嵌套循環使用單個 lapply。 還顯示了第一個循環的轉換:

## setting drop=TRUE ensures that each split has at least 1 row, which allows
## you to extract the split value, e.g. Surname
Split.TYPE1 <- split(TYPE1, TYPE1$Surname, drop=TRUE) 
Split.TYPE2a <- split(TYPE2, TYPE2[,c("Surname", "Name")], drop=TRUE)


##--------------------------------- Save the TYPE 1 reports---------------------------------------
lapply(Split.TYPE1, function(d1) {
    nm = d1$Surname[1]
    ## use nm and d1 as before
}

##------------------------------ Save the TYPE 2 in a folder ----------------------------------
lapply(Split.TYPE2a, function(d1) {
    dnn = d1$Surname[1]
    fn = d1$Name[1]
    ## you may want to move dnn out of lapply, otherwise the same directory name
    ## will be used multiple times
    ##
    ## use fn and d1 as before
})

暫無
暫無

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

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