簡體   English   中英

如何在R中循環訪問CSV文件的文件夾

[英]How to loop through a folder of CSV files in R

我有一個文件夾,其中包含一堆標題為“yob1980”,“yob1981”,“yob1982”等的CSV文件。

我必須使用for循環遍歷每個文件並將其內容放入數據框 - 數據框中的列應為“1980”,“1981”,“1982”等

這是我有的:

file_list <- list.files()

temp = list.files(pattern="*.txt")
babynames <- do.call(rbind,lapply(temp,read.csv, FALSE))

names(babynames) <- c("Name", "Gender", "Count")

我覺得我需要一個for循環,但我不確定如何遍歷文件。 有人指出我正確的方向嗎?

考慮lapply()的匿名函數:

files = list.files(pattern="*.txt")

dfList <- lapply(files, function(i) {
     df <- read.csv(i, header=FALSE, col.names=c("Name", "Gender", "Count"))
     df$Year <- gsub("yob", "", i) 
     return(df)
})

finaldf <- do.call(rbind, dflist)

我最喜歡的方式做到這一點是使用ldplyplyr包。 它具有返回數據幀的優點,因此您不需要在之后執行rbind步驟:

library( plyr )
babynames <- ldply( .data = list.files(pattern="*.txt"),
                    .fun = read.csv,
                    header = FALSE,
                    col.names=c("Name", "Gender", "Count") )

另外一個好處是,您可以非常輕松地對導入進行多線程處理,從而可以更快地導入大型多文件數據集:

library( plyr )
library( doMC )
registerDoMC( cores = 4 )
babynames <- ldply( .data = list.files(pattern="*.txt"),
                    .fun = read.csv,
                    header = FALSE,
                    col.names=c("Name", "Gender", "Count"),
                    .parallel = TRUE )

稍微更改上面的內容以在結果數據框中包含Year列,您可以先創建一個函數,然后在ldply中執行該函數, ldply執行read.csv

readFun <- function( filename ) {

    # read in the data
    data <- read.csv( filename, 
                      header = FALSE, 
                      col.names = c( "Name", "Gender", "Count" ) )

    # add a "Year" column by removing both "yob" and ".txt" from file name
    data$Year <- gsub( "yob|.txt", "", filename )

    return( data )
}

# execute that function across all files, outputting a data frame
doMC::registerDoMC( cores = 4 )
babynames <- plyr::ldply( .data = list.files(pattern="*.txt"),
                          .fun = readFun,
                          .parallel = TRUE )

這將以簡潔的方式為您提供數據,這就是我建議從這里向前推進的方式。 雖然可以將每年的數據分成它自己的專欄,但這可能不是最好的方法。

注意:根據您的偏好,將Year列轉換為integer類可能是個好主意。 但這取決於你。

使用purrr

library(tidyverse)

files <- list.files(path = "./data/", pattern = "*.csv")

df <- files %>% 
    map(function(x) {
        read.csv(paste0("./data/", x))
    }) %>%
    reduce(rbind)

在這種情況下, for循環可能比lapply更合適。

file_list = list.files(pattern="*.txt")
data_list <- vector("list", "length" = length(file.list))

for (i in seq_along(file_list)) {
    filename = file_list[[i]]

    # Read data in
    df <- read.csv(filename, header = FALSE, col.names = c("Name", "Gender", "Count"))

    # Extract year from filename
    year = gsub("yob", "", filename)
    df[["Filename"]] = year

    # Add year to data_list
    data_list[[i]] <- df
}

babynames <- do.call(rbind, data_list)

暫無
暫無

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

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