Coś takiego jak poniżej powinno skutkować każdą ramką danych jako oddzielnym elementem na pojedynczej liście:
temp = list.files(pattern="*.csv")
myfiles = lapply(temp, read.delim)
Zakłada się, że te pliki CSV znajdują się w jednym katalogu - bieżącym katalogu roboczym - i że wszystkie mają małe litery .csv
.
Jeśli następnie chcemy połączyć te ramki danych w jednej ramce danych, zobacz rozwiązania w innych odpowiedzi za pomocą takich rzeczy do.call(rbind,...)
, dplyr::bind_rows()
albo data.table::rbindlist()
.
Jeśli naprawdę chcesz każdej ramki danych w oddzielnym obiekcie, nawet jeśli jest to często niewskazane, możesz wykonać następujące czynności assign
:
temp = list.files(pattern="*.csv")
for (i in 1:length(temp)) assign(temp[i], read.csv(temp[i]))
Lub bez assign
i, aby zademonstrować (1), jak można wyczyścić nazwę pliku i (2) pokazać, jak używać list2env
, możesz wypróbować następujące czynności:
temp = list.files(pattern="*.csv")
list2env(
lapply(setNames(temp, make.names(gsub("*.csv$", "", temp))),
read.csv), envir = .GlobalEnv)
Ale znowu często lepiej pozostawić je na jednej liście.
A5C1D2H2I1M1N2O1R2T1
źródło
assign
... Jeśli chcesz, aby przypisane wartości znajdowały się w środowisku globalnym, upewnij się, że ustawiłeśinherits=T
.tidyverse
Szybkie i zwięzłe rozwiązanie: (ponad dwa razy szybsze niż Base Rread.csv
)i data.table „s
fread()
można nawet wyciąć te czasy ładowania o połowę ponownie. (dla 1/4 podstawy czasu R )stringsAsFactors = FALSE
Argumentem utrzymuje wolny współczynnik dataframe (i jak zaznacza MARBEL jest domyślne ustawienie,fread
)Jeśli rzutowanie jest bezczelne, możesz wymusić, aby wszystkie kolumny były znakami z
col_types
argumentem.Jeśli chcesz zanurzyć się w podkatalogach, aby skonstruować listę plików do ostatecznego powiązania, pamiętaj, aby podać nazwę ścieżki, a także zarejestrować pliki z ich pełnymi nazwami na liście. Umożliwi to kontynuowanie pracy wiązania poza bieżącym katalogiem. (Myślenie o pełnych nazwach ścieżek jako paszportach umożliwiających powrót z powrotem do „granic” katalogu).
Jak Hadley opisuje tutaj (mniej więcej w połowie):
Funkcja bonusowa - dodawanie nazw plików do rekordów zgodnie z żądaniem funkcji Niksa w komentarzach poniżej:
* Dodaj oryginał
filename
do każdego rekordu.Kod wyjaśniony: utwórz funkcję dodawania nazwy pliku do każdego rekordu podczas początkowego odczytu tabel. Następnie użyj tej funkcji zamiast prostej
read_csv()
funkcji.(Metody rzutowania i obsługi podkatalogów można również obsługiwać wewnątrz
read_plus()
funkcji w taki sam sposób, jak pokazano w drugim i trzecim wariancie sugerowanym powyżej.)Przypadek użycia pośredniego
Większy przypadek użycia
Różne przypadki użycia
Wiersze: liczba plików (1000, 100, 10)
Kolumny: ostateczny rozmiar ramki danych (5 MB, 50 MB, 500 MB)
(kliknij obraz, aby zobaczyć oryginalny rozmiar)
Podstawowe wyniki R są lepsze dla najmniejszych przypadków użycia, w których narzut związany z doprowadzeniem bibliotek C purrr i dplyr do zniesienia przewyższa wzrost wydajności, który obserwuje się podczas wykonywania zadań przetwarzania na większą skalę.
jeśli chcesz uruchomić własne testy, ten skrypt bash może ci się przydać.
bash what_you_name_this_script.sh "fileName_you_want_copied" 100
utworzy 100 kopii pliku kolejno numerowanych (po pierwszych 8 znakach nazwy pliku i podkreśleniu).Atrybucje i podziękowania
Specjalne podziękowania dla:
map_df()
tutaj .fread()
. (Muszę się uczyćdata.table
.)źródło
readAddFilename <- function(flnm) { read_csv(flnm) %>% mutate(filename = flnm) }
po prostu upuść to w miejscemap_df
zamiast zwykłego tylko do odczytu,read_csv()
które jest teraz. Mogę zaktualizować powyższy wpis, aby pokazać funkcję i sposób dopasowania do potoku, jeśli nadal masz pytania lub uważasz, że to będzie pomocne.read_csv
jest on znacznie wolniejszy niżfread
. Dodałbym punkt odniesienia, jeśli chcesz powiedzieć, że coś jest szybsze. Jednym z pomysłów jest utworzenie 30 plików 1 GB i ich odczytanie, w takim przypadku liczy się wydajność.fread()
i dplyr ” sread_csv()
: 14,2 vs 19,9 sek. TBH, porównywałem tylko bazę R do dplyr i ponieważread_csv()
jest to około 2-4x szybsze niżread.csv()
, testowanie porównawcze nie wydawało się konieczne. Interesujące było jednakfread()
zawirowanie i zatrzymanie się, aby sprawdzić bardziej kompletne wyniki testów porównawczych. Dzięki jeszcze raz!Oto niektóre opcje konwersji plików .csv w jedną ramkę danych. Przy użyciu bazy R i niektórych dostępnych pakietów do odczytu plików w języku R.
Jest to wolniejsze niż poniższe opcje.
Edycja: - Kilka dodatkowych opcji za pomocą
data.table
ireadr
fread()
Wersja, która jest funkcjądata.table
pakietu. Jest to zdecydowanie najszybszy opcji w R .Korzystanie z readr , który jest kolejnym pakietem do odczytu plików csv. Jest wolniejszy niż
fread
, szybszy niż podstawa R, ale ma różne funkcje.źródło
data.table
wersję, która powinna poprawić wydajność.do.call
Oprócz użycia
lapply
lub innej konstrukcji pętlowej w R możesz połączyć swoje pliki CSV w jeden plik.W Uniksie, jeśli pliki nie mają nagłówków, jest to tak proste jak:
lub jeśli są nagłówki i możesz znaleźć ciąg pasujący do nagłówków i tylko nagłówki (tj. załóżmy, że wszystkie nagłówki zaczynają się od „Wiek”), zrobiłbyś:
Myślę, że w systemie Windows można to zrobić za pomocą
COPY
iSEARCH
(lubFIND
coś w tym stylu) z okna poleceń DOS, ale dlaczego nie zainstalowaćcygwin
i uzyskać mocy powłoki poleceń Uniksa?źródło
Git
instalacją?To jest kod, który opracowałem, aby odczytać wszystkie pliki csv do R. Stworzy ramkę danych dla każdego pliku csv indywidualnie i nada tytułowi ramkę danych oryginalnej nazwy pliku (usuwając spacje i .csv) Mam nadzieję, że okaże się przydatny!
źródło
Trzy najlepsze odpowiedzi: @ A5C1D2H2I1M1N2O1R2T1, @leerssej i @marbel i wszystkie są zasadniczo takie same: zastosuj fread do każdego pliku, a następnie rbind / rbindlist powstałe tabele danych. Zwykle używam
rbindlist(lapply(list.files("*.csv"),fread))
formularza.Jest to lepsze niż inne R-wewnętrzne alternatywy i w porządku dla niewielkiej liczby dużych plików csv, ale nie jest najlepsze dla dużej liczby małych plików csv, gdy liczy się prędkość. W takim przypadku pierwsze użycie może być znacznie szybsze
cat
, jak sugeruje @Spacedman w odpowiedzi na 4. miejscu. Dodam kilka szczegółów, jak to zrobić z poziomu R:Co jednak, jeśli każdy plik csv ma nagłówek?
A co, jeśli masz tyle plików, że
*.csv
glob powłoki nie działa?A jeśli wszystkie pliki mają nagłówek ORAZ jest ich zbyt wiele?
A co, jeśli wynikowy połączony plik csv jest zbyt duży dla pamięci systemowej?
Z nagłówkami?
Wreszcie, co jeśli nie chcesz wszystkich plików .csv w katalogu, a raczej określonego zestawu plików? (Ponadto wszystkie mają nagłówki.) (To jest mój przypadek użycia.)
i jest to mniej więcej taka sama prędkość jak zwykły fread xargs cat :)
Uwaga: w przypadku data.table przed wersją 1.1.6 (19 września 2018 r.) Pomiń opcję
cmd=
odfread(cmd=
.Dodatek: użycie mclapply biblioteki równoległej zamiast seryjnego lapply, np.,
rbindlist(lapply(list.files("*.csv"),fread))
Jest również znacznie szybsze niż rbindlist lapply fread.Czas odczytać 121401 plików csv w pojedynczej tabeli danych. Każdy plik csv ma 3 kolumny, jeden wiersz nagłówka i średnio 4.510 wierszy. Maszyna jest maszyną wirtualną GCP z 96 rdzeniami:
Podsumowując, jeśli interesuje Cię szybkość i masz wiele plików i wiele rdzeni, fread xargs cat jest około 50 razy szybszy niż najszybsze rozwiązanie w 3 najlepszych odpowiedziach.
źródło
Moim zdaniem, większość pozostałych odpowiedzi jest nieaktualna
rio::import_list
, co jest zwięzłym, jednostronnym tekstem:Wszelkie dodatkowe argumenty są przekazywane do
rio::import
.rio
radzi sobie z prawie dowolnego pliku formatu R może czytać i używadata.table
„sfread
gdzie jest to możliwe, więc powinno być zbyt szybko.źródło
Użycie
plyr::ldply
tej.parallel
opcji powoduje zwiększenie prędkości o około 50% poprzez włączenie opcji podczas odczytu 400 plików csv około 30-40 MB każdy. Przykład zawiera pasek postępu tekstu.źródło
fread
lubuser-defined functions
? Dzięki!?ldply
pokazuje...
inne argumenty przekazywane do.fun
. Korzystanie albofread, skip = 100
czyfunction(x) fread(x, skip = 100)
będzie działaćfunction(x) fread(x, skip = 100)
nie działało dla mnie, ale załatwienie dodatkowych argumentów po nazwie funkcji nie działało. Dzięki jeszcze raz!Opierając się na komentarzu dnlbrk, przypisywanie może być znacznie szybsze niż list2env dla dużych plików.
Po ustawieniu argumentu full.names na true, otrzymasz pełną ścieżkę do każdego pliku jako osobny ciąg znaków na liście plików, np. List_of_file_paths [1] będzie wyglądał jak „C: / Users / Anon / Documents / Folder_with_csv_files / file1.csv ”
Możesz użyć fread lub dataR pakietu read.csv pakietu data.table zamiast read_csv. Krok nazwa_pliku pozwala uporządkować nazwę, tak aby każda ramka danych nie pozostawała z pełną ścieżką do pliku, jak sama nazwa. Możesz rozszerzyć pętlę, aby zrobić dalsze rzeczy w tabeli danych przed przeniesieniem jej do środowiska globalnego, na przykład:
źródło
Oto mój konkretny przykład, aby odczytać wiele plików i połączyć je w 1 ramkę danych:
źródło
rbindlist()
oddata.table
Poniższe kody powinny zapewnić najszybszą prędkość dużych zbiorów danych, o ile masz wiele rdzeni na komputerze:
Zaktualizowano w 2020/04/16: Gdy znajduję nowy pakiet dostępny do obliczeń równoległych, dostępne jest alternatywne rozwiązanie przy użyciu następujących kodów.
źródło
I jak podejście z użyciem
list.files()
,lapply()
ilist2env()
(afs::dir_ls()
,purrr::map()
alist2env()
). To wydaje się proste i elastyczne.Alternatywnie możesz wypróbować mały pakiet { tor } ( do-R ): Domyślnie importuje pliki z katalogu roboczego do listy (
list_*()
warianty) lub do środowiska globalnego (load_*()
warianty).Na przykład tutaj czytam wszystkie pliki .csv z mojego katalogu roboczego na listę, używając
tor::list_csv()
:A teraz ładuję te pliki do mojego globalnego środowiska za pomocą
tor::load_csv()
:Jeśli potrzebujesz odczytać określone pliki, możesz dopasować ich ścieżkę do pliku za pomocą
regexp
,ignore.case
iinvert
.Dla jeszcze większej elastyczności użytkowania
list_any()
. Pozwala podać funkcję czytnika za pomocą argumentu.f
.Przekaż dodatkowe argumenty przez ... lub wewnątrz funkcji lambda.
źródło
Zażądano dodania tej funkcji do pakietu Stackoverflow R. Biorąc pod uwagę, że jest to pakiet maleverseverse (i nie może zależeć od pakietów stron trzecich), oto co wymyśliłem:
Poprzez parametryzację funkcji czytnika i reduktora ludzie mogą korzystać z data.table lub dplyr, jeśli tak chcą, lub po prostu użyć podstawowych funkcji R, które są odpowiednie dla mniejszych zestawów danych.
źródło