Mam więc plik danych (oddzielony średnikami), który zawiera dużo szczegółów i niekompletne wiersze (prowadząc Access i SQL do dławienia). Jest to zestaw danych na poziomie hrabstwa podzielony na segmenty, podsegmenty i podsegmenty (łącznie ~ 200 czynników) przez 40 lat. Krótko mówiąc, jest ogromny i nie zmieści się w pamięci, jeśli spróbuję go po prostu przeczytać.
Więc moje pytanie jest takie, biorąc pod uwagę, że chcę wszystkie hrabstwa, ale tylko jeden rok (i tylko najwyższy poziom segmentu ... prowadzący do około 100 000 wierszy na końcu), jaki byłby najlepszy sposób na uzyskanie ten pakiet zbiorczy w R?
Obecnie staram się odciąć nieistotne lata z Pythonem, omijając limit rozmiaru pliku, czytając i działając w jednej linii na raz, ale wolałbym rozwiązanie tylko R (pakiety CRAN OK). Czy istnieje podobny sposób wczytywania w plikach fragmentu na raz w R?
Wszelkie pomysły będą mile widziane.
Aktualizacja:
- Ograniczenia
- Musi używać mojego komputera, więc nie ma instancji EC2
- Jak najbardziej R-only. Szybkość i zasoby nie są w tym przypadku problemem ... pod warunkiem, że mój komputer nie eksploduje ...
- Jak widać poniżej, dane zawierają typy mieszane, na których będę musiał później operować
- Dane
- Dane mają pojemność 3,5 GB, około 8,5 miliona wierszy i 17 kolumn
- Kilka tysięcy wierszy (~ 2k) jest zniekształconych, a tylko jedna kolumna zamiast 17
- Są całkowicie nieistotne i można je porzucić
- Potrzebuję tylko ~ 100 000 wierszy z tego pliku (patrz poniżej)
Przykład danych:
County; State; Year; Quarter; Segment; Sub-Segment; Sub-Sub-Segment; GDP; ...
Ada County;NC;2009;4;FIRE;Financial;Banks;80.1; ...
Ada County;NC;2010;1;FIRE;Financial;Banks;82.5; ...
NC [Malformed row]
[8.5 Mill rows]
Chcę wyciąć kilka kolumn i wybrać dwa z 40 dostępnych lat (2009-2010 od 1980-2020), aby dane pasowały do R:
County; State; Year; Quarter; Segment; GDP; ...
Ada County;NC;2009;4;FIRE;80.1; ...
Ada County;NC;2010;1;FIRE;82.5; ...
[~200,000 rows]
Wyniki:
Po majstrowaniu przy wszystkich sugestiach zdecydowałem, że najlepiej sprawdzi się readLines, zaproponowane przez JD i Marka. Dałem Markowi czek, bo dał przykładową realizację.
Aby uzyskać ostateczną odpowiedź, odtworzyłem nieco dostosowaną wersję implementacji Marka, używając strsplit i cat, aby zachować tylko wybrane kolumny.
Należy również zauważyć, że jest to DUŻO mniej wydajne niż Python ... tak jak w przypadku, Python przeskakuje plik 3,5 GB w 5 minut, podczas gdy R zajmuje około 60 ... ale jeśli wszystko, co masz, to R, to jest to bilet.
## Open a connection separately to hold the cursor position
file.in <- file('bad_data.txt', 'rt')
file.out <- file('chopped_data.txt', 'wt')
line <- readLines(file.in, n=1)
line.split <- strsplit(line, ';')
# Stitching together only the columns we want
cat(line.split[[1]][1:5], line.split[[1]][8], sep = ';', file = file.out, fill = TRUE)
## Use a loop to read in the rest of the lines
line <- readLines(file.in, n=1)
while (length(line)) {
line.split <- strsplit(line, ';')
if (length(line.split[[1]]) > 1) {
if (line.split[[1]][3] == '2009') {
cat(line.split[[1]][1:5], line.split[[1]][8], sep = ';', file = file.out, fill = TRUE)
}
}
line<- readLines(file.in, n=1)
}
close(file.in)
close(file.out)
Błędy według podejścia:
- sqldf
- Z pewnością tego będę używał do tego typu problemów w przyszłości, jeśli dane są dobrze sformułowane. Jeśli jednak tak nie jest, dławiki SQLite.
- MapReduce
- Szczerze mówiąc, doktorzy trochę mnie onieśmielali, więc nie próbowałem tego. Wyglądało na to, że wymagało to, aby obiekt był również w pamięci, co podważyłoby sedno sprawy, gdyby tak było.
- bigmemory
- To podejście jest czysto połączone z danymi, ale może obsługiwać tylko jeden typ na raz. W rezultacie wszystkie moje wektory postaci spadły, gdy zostały umieszczone w dużej tabeli. Jeśli jednak muszę zaprojektować duże zestawy danych na przyszłość, rozważałbym użycie liczb tylko po to, aby utrzymać tę opcję przy życiu.
- skanowanie
- Scan wydawał się mieć podobne problemy jak duża pamięć, ale z całą mechaniką readLines. Krótko mówiąc, tym razem po prostu nie pasowało do rachunku.
sed
i / lubawk
utworzeniu skróconej wersji pliku CSV, którą możesz przeczytać bezpośrednio. Ponieważ jest to raczej obejście niż odpowiedź, zostawię to w komentarzu.