Импорт нескольких.csv файлы в R
предположим, что у нас есть папка, содержащая несколько данных.csv-файлы, каждый из которых содержит одинаковое количество переменных, но каждый из разных времен.
Есть ли способ в R импортировать их все одновременно, а не импортировать их все по отдельности?
моя проблема заключается в том, что у меня есть около 2000 файлов данных для импорта и необходимости импортировать их по отдельности только с помощью кода:
read.delim(file="filename", header=TRUE, sep="t")
не очень эффективно.
13 ответов:
что-то вроде следующего должно привести к тому, что каждый фрейм данных будет отдельным элементом в одном списке:
temp = list.files(pattern="*.csv") myfiles = lapply(temp, read.delim)это предполагает, что у вас есть эти CSV в одном каталоге-ваш текущий рабочий каталог-и что все они имеют расширение нижнего регистра
.csv.если вы хотите объединить эти фреймы данных в один фрейм данных, см. решения в других ответах, используя такие вещи, как
do.call(rbind,...),dplyr::bind_rows()илиdata.table::rbindlist().если вы действительно хотите, чтобы каждый фрейм данных был отдельным объектом, хотя это часто нецелесообразно, вы можете сделать следующее с
assign:temp = list.files(pattern="*.csv") for (i in 1:length(temp)) assign(temp[i], read.csv(temp[i]))или
assign, и продемонстрировать, (1) как имя файла может быть очищено и (2) показывают, как использоватьlist2env, вы можете попробовать следующее:temp = list.files(pattern="*.csv") list2env( lapply(setNames(temp, make.names(gsub("*.csv$", "", temp))), read.csv), envir = .GlobalEnv)но опять же, это часто лучше оставить их в одном списке.
вот еще один вариант для преобразования .csv файлы в один данных.рамка. Использование R базовых функций. Это на порядок медленнее, чем варианты ниже.
# Get the files names files = list.files(pattern="*.csv") # First apply read.csv, then rbind myfiles = do.call(rbind, lapply(files, function(x) read.csv(x, stringsAsFactors = FALSE)))Edit: - еще несколько дополнительных вариантов, с помощью
data.tableиreadrA
fread()версия, которая является функцией . Это должен быть самый быстрый вариант.library(data.table) DT = do.call(rbind, lapply(files, fread) # the same using `rbindlist()` DT = rbindlist(lapply(files, fread))используя readr, который является новым пакетом hadley для чтения csv-файлов. Немного медленнее, чем fread, но с различными функциональными возможностями.
library(readr) library(dplyr) tbl = lapply(files, read_csv) %>% bind_rows()
быстрый и лаконичный
tidyverseрешение: (более чем в два раза быстрее база Rread.csv)tbl <- list.files(pattern = "*.csv") %>% map_df(~read_csv(.))данные.таблица ' s
fread()смогите даже отрезать те времена нагрузки в половине.library(data.table) tbl_fread <- list.files(pattern = "*.csv") %>% map_df(~fread(., stringsAsFactors = FALSE))The
stringsAsFactors = FALSEаргумент сохраняет фактор фрейма данных свободным.если типирование является нахальным, вы можете заставить все столбцы быть как символы с
col_typesаргумент.tbl <- list.files(pattern = "*.csv") %>% map_df(~read_csv(., col_types = cols(.default = "c")))если вы хотите погрузиться в подкаталоги, чтобы построить свой список файлов для последующей привязки, то обязательно включите имя пути, а также зарегистрируйте файлы с их полными именами в своем списке. Это позволит выполнить привязку за пределами текущего каталога. (Думая о полных именах путей как работающих как паспорта, чтобы позволить движение назад через каталог "границы".)
tbl <- list.files(path = "./subdirectory/", pattern = "*.csv", full.names = T) %>% map_df(~read_csv(., col_types = cols(.default = "c")))как описывает Хэдли здесь (примерно на полпути вниз):
map_df(x, f)существоdo.call("rbind", lapply(x, f))....Бонус -добавление имен файлов в записи на запрос функции Niks в комментариях ниже:
* Добавить оригиналfilenameдля каждой записи.code explained: сделайте функцию для добавления имени файла к каждой записи во время первоначального чтения таблиц. Затем используйте эту функцию вместо простого
а также с помощью
lapplyили некоторые другие циклические конструкции в R вы можете объединить свои CSV-файлы в один файл.в Unix, если файлы не имели заголовков, то его так просто, как:
cat *.csv > all.csvили если есть заголовки, и вы можете найти строку, которая соответствует заголовкам и только заголовки (т. е. предположим, что строки заголовка все начинаются с "Возраст"), вы бы сделали:
cat *.csv | grep -v ^Age > all.csvЯ думаю, что в Windows вы могли бы сделать это с
COPYиSEARCH(илиFINDили что-то) от Окно команды DOS, но почему бы не установитьcygwinи получить власть командной оболочки Unix?
Это код, который я разработал для чтения всех файлов csv в R. он создаст фрейм данных для каждого файла csv отдельно и название, которое будет содержать исходное имя файла (удаление пробелов и т. д.csv) я надеюсь, что вы найдете его полезным!
path <- "C:/Users/cfees/My Box Files/Fitness/" files <- list.files(path=path, pattern="*.csv") for(file in files) { perpos <- which(strsplit(file, "")[[1]]==".") assign( gsub(" ","",substr(file, 1, perpos-1)), read.csv(paste(path,file,sep=""))) }
используя
plyr::ldplyесть примерно 50% увеличение скорости при включении.parallelопция при чтении 400 csv файлов примерно по 30-40 МБ каждый. Пример включает в себя текстовый прогрессбар.library(plyr) library(data.table) library(doSNOW) csv.list <- list.files(path="t:/data", pattern=".csv$", full.names=TRUE) cl <- makeCluster(4) registerDoSNOW(cl) pb <- txtProgressBar(max=length(csv.list), style=3) pbu <- function(i) setTxtProgressBar(pb, i) dt <- setDT(ldply(csv.list, fread, .parallel=TRUE, .paropts=list(.options.snow=list(progress=pbu)))) stopCluster(cl)
на мой взгляд, большинство других ответов заменен на
rio::import_list, который является кратким однострочным:library(rio) my_data <- import_list(dir("path_to_directory", pattern = ".csv", rbind = TRUE))любые дополнительные аргументы передаются
rio::import.rioможет иметь дело практически с любым форматом файла R может читать, и он используетdata.table' sfreadгде это возможно, так что это должно быть слишком быстро.
основываясь на комментарии dnlbrk, назначить может быть значительно быстрее, чем list2env для больших файлов.
library(readr) library(stringr) List_of_file_paths <- list.files(path ="C:/Users/Anon/Documents/Folder_with_csv_files/", pattern = ".csv", all.files = TRUE, full.names = TRUE)установив в полном объеме.names аргумент true, вы получите полный путь к каждому файлу в виде отдельной строки символов в вашем списке файлов, например, List_of_file_paths[1] будет что-то вроде "C:/Users/Anon/Documents/Folder_with_csv_files/file1.csv"
for(f in 1:length(List_of_filepaths)) { file_name <- str_sub(string = List_of_filepaths[f], start = 46, end = -5) file_df <- read_csv(List_of_filepaths[f]) assign( x = file_name, value = file_df, envir = .GlobalEnv) }вы можете использовать данные.прочитанный fread или основание R пакета таблицы.csv вместо read_csv. Этот file_name шаг позволяет привести в порядок имя, так что каждый фрейм данных не остается с полным путем к файлу, как это имя. Вы можете расширить свой цикл, чтобы сделать дальнейшие действия с таблицей данных перед ее передачей в глобальную среду, например:
for(f in 1:length(List_of_filepaths)) { file_name <- str_sub(string = List_of_filepaths[f], start = 46, end = -5) file_df <- read_csv(List_of_filepaths[f]) file_df <- file_df[,1:3] #if you only need the first three columns assign( x = file_name, value = file_df, envir = .GlobalEnv) }
моя вилка принятого ответа немного быстрее и удаляет
.csvот имени объекта в р.temp = list.files(pattern="*.csv") for (i in 1:length(temp)) assign(gsub(".csv", "", temp[i]), read_csv(temp[i]))он полагается на
readrпакета (т. е.library(readr)). Вы могли бы сделать что-то подобное сdata.tableпри желании.
Я использую это успешно:
xlist<-list.files(pattern = "*.csv") for(i in xlist) { x <- read.csv((i)) assign(i, x) }
Если вы хотите собрать разные csv-файлы в одни данные.кадр, вы можете использовать следующее. обратите внимание, что данные" x".кадр должен быть создан заранее.
temp <- list.files(pattern="*.csv") for (i in 1:length(temp)) { temp2 = read.csv(temp[i], header = TRUE) x <- rbind(x,temp2) }
вы можете использовать superb
sparklyrпакет для этого:# RStudio will help you get set-up with the Spark dependencies library(sparklyr) library(dplyr) sc <- spark_connect(master = "local", version = "2.0.2") df <- spark_read_csv(sc, "dummy", "file:////Users/bob/dev/data/results/*/*/*-metrics.csv") %>% collect()
Это часть моего сценария.
#This cycle read the files in a directory and assign the filenames to datasets files <- list.files(pattern=".csv$") for(i in files) { X <- read.table(i, header=TRUE) SN<-X$A/X$B X<-cbind(X,SN) ds<-paste("data_",i, sep="")#this add "data_" to the name of file ds<-substr(ds, 1, nchar(ds)-4)#remove the last 4 char (.csv) assign(ds, X) }
Comments