2010-02-03 23 views
38

Mam bardzo duże pliki z ograniczonymi danymi i Chcę przetworzyć tylko niektóre kolumny w R bez zajmowania czasu i pamięci, aby utworzyć data.frame dla cały plik.Sposoby czytania tylko wybierz kolumny z pliku na R? (Szczęśliwe medium pomiędzy `read.table` a` scan`?)

Jedyne dostępne opcje to read.table, co jest bardzo nieekonomiczne, gdy chcę tylko kilka kolumn lub scan, które wydają się zbyt niskie dla tego, co chcę.

Czy jest lepsza opcja, czy to z czystym R, czy może wywołując inny skrypt powłoki, aby wyodrębnić kolumnę, a następnie używając skanowania lub read.table na jego wyjściu? (Co prowadzi do pytania, jak wywołać skrypt powłoki i przechwycić jego wyniki w R?).

+0

Cały zestaw przydatnych odpowiedzi tutaj. Każda z nich byłaby pomocna w danym kontekście. Ten zaakceptowany był po prostu najbliższy mojej faktycznej sprawie i zawierał fragment kodu. (Mogłem po prostu dobrze wybrać Dirka, ale wygląda na to, że ma już dużo reputacji ;-)) –

+6

Najlepsza odpowiedź to nowe pytanie http://stackoverflow.com/q/5788117/168747 – Marek

Odpowiedz

34

Czasem robię coś takiego, kiedy mam dane w pliku rozdzielany tabulatorami:

df <- read.table(pipe("cut -f1,5,28 myFile.txt")) 

Umożliwia to wybór danych, które można wykonać bez korzystania z dużej ilości pamięci.

Zobacz Only read limited number of columns dla czystej wersji R, używając "NULL" w argumencie colClasses do read.table.

+1

Twój pierwszy przykład jest dokładnie tym, czego użyłem w końcu.(awk zamiast cięcia w moim przypadku z powodu nieregularnego formatu plików rozdzielanych). Twój drugi przykład nie jest tak naprawdę równoważny, jak rozumiem. Czy nie stworzy on całego 'data.frame', tylko po to, by go ponownie wyrzucić? Kiedy chcę 2 z 10 kolumn z pliku z milionem wierszy, który różni się znacznie wydajnością. –

+11

Nie, czysty równoważnik R byłby jak (zakładając 28 kolumn) 'mycols <- rep (NULL, 28); mycols [c (1,5,28)] <- NA; df <- read.table (plik, colClasses = mycols) ' –

+1

@DirkEddelbuettel Właśnie na tym poległem. Wygląda na to, że 'NULL' musi być w cudzysłowach. – JackeJR

18

Jedną z możliwości jest użycie pipe() zamiast nazwy pliku i mają awk lub podobnych filtrów wyodrębnić tylko kolumny, które chcesz.

Zobacz help(connection), aby uzyskać więcej informacji na temat pipe oraz znajomych.

Edit: read.table() może zrobić dla ciebie, jeśli jesteś bardzo wyraźny o colClasses - wartość NULL dla danej kolumny pomija kolumnę alltogether. Zobacz help(read.table). Mamy więc rozwiązanie w bazie R bez dodatkowych pakietów lub narzędzi.

7

Myślę, że podejście Dirka jest proste i szybkie. Alternatywą, którą użyłem, jest załadowanie danych do sqlite, który ładuje DUŻO szybciej niż read.table(), a następnie wyciąga tylko to, co chcesz. pakiet sqldf() sprawia, że ​​wszystko jest całkiem proste. Here's a link do poprzedniej odpowiedzi przepełnienia stosu, która podaje przykłady kodu dla funkcji sqldf().

3

Jest to prawdopodobnie więcej niż trzeba, ale jeśli jesteś działających na bardzo dużych zbiorów danych następnie można również spojrzeć na the HadoopStreaming package który dostarcza map-zredukować stosując rutynowe Hadoop.

7

Jest to pakiet, colbycol, mające na celu dokładnie to, co szukasz:

http://cran.r-project.org/web/packages/colbycol/index.html

+1

W rzeczywistości wygląda na to, że wciąż przetwarza wszystkie kolumny, ale bez ograniczeń w pamięci. Może być bardzo użyteczny w nieco innym kontekście. –

+2

Ten pakiet nie jest już dostępny w CRAN. –