Импорт нескольких.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
и readr
A 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
решение:
(более чем в два раза быстрее база R read.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))
на 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
для каждой записи.
код объяснен: сделайте функцию для добавления имени файла к каждой записи во время начального чтения таблиц. Затем используйте эту функцию вместо простого
а также с помощью 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-файла отдельно и заголовок, который dataframe оригинальное имя файла (удаление пробелов и .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
' s fread
где это возможно, поэтому он должен быть быстрым.
основываясь на комментарии dnlbrk, assign может быть значительно быстрее, чем 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 или base 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)
}