Otwieranie plików
Często zdarza się, że dane, na których chcemy pracować są zapisane w pliku. Zamiast przeklejać je pracowicie do R-a możemy je wczytać bezpośrednio, np. za pomocą polecenia read.table():
> dane_z_pliku = read.table("plik_z_danymi")
Jeśli mój plik plik_z_danymi wyglądał tak:
0.4 11 19
432 432 101
11 1.1 0.43
28 82 10
To na dane_z_pliku zostało zapisane takie coś:
> dane_z_pliku V1 V2 V3 1 0.4 11.0 19.00 2 432.0 432.0 101.00 3 11.0 1.1 0.43 4 28.0 82.0 10.00
Wygląda trochę jak macierz, prawda? Ale to nie macierz, tylko data frame (ramka danych); o data frame'ach trochę więcej będzie później. Na razie możesz poeksperymentować i zobaczyć, jakie polecenia działają podobnie jak na macierzy, a jakie trochę inaczej (polecam np. sprawdzenie dane_z_pliku[2] i dane_z_pliku[2,3]). V1, V2 i V3 to nazwy, które R domyślnie nadał kolumnom tej tabeli, a 1, 2, 3 i 4 to domyślne nazwy wierszy.
Oczywiście plik plik_z_danymi znajdował się u mnie w tym samym miejscu, w którym R właśnie pracował. Może znajdować się gdzie indziej, ale wtedy trzeba podać całą ścieżkę do pliku:
> dane_z_pliku = read.table("C:/moje_dane/tabela_z_danymi.txt")
Jeśli nie jesteś pewien/pewna, gdzie R pracuje, można to sprawdzić za pomocą polecenia getwd() (jak get working directory):
> getwd() [1] "/home/maciosz/vinci/r-tutorial"
A jeśli chcesz zmienić miejsce pracy R-a, możesz to zrobić za pomocą funkcji setwd() (set working directory):
Przy wpisywaniu ścieżki możesz nacisnąć tabulator, żeby R podowiedział Ci, jakie katalogi / pliki możesz wpisać.
I jeszcze jedna pożyteczna funkcja, wylistowująca pliki w danym katalogu:
> list.files()
Funkcja read.table() ma trochę pożytecznych argumentów. Argumenty to to, co podajemy funkcji w nawiasach, wpływając na to, jak działa; czasem argument jest niezbędny (np. read.table() nie miałaby sensu bez podania nazwy pliku), czasem opcjonalny - domyślnie funkcja robi cośtam, a za pomocą opcjonalnego argumentu może robić coś trochę innego. Argumenty możesz przejrzeć wyświetlając helpa tej funkcji:
> ?read.table
lub korzystając z funkcji args(), wyświetlającej argumenty funkcji:
> args(read.table) function (file, header = FALSE, sep = "", quote = "\"'", dec = ".", numerals = c("allow.loss", "warn.loss", "no.loss"), row.names, col.names, as.is = !stringsAsFactors, na.strings = "NA", colClasses = NA, nrows = -1, skip = 0, check.names = TRUE, fill = !blank.lines.skip, strip.white = FALSE, blank.lines.skip = TRUE, comment.char = "#", allowEscapes = FALSE, flush = FALSE, stringsAsFactors = default.stringsAsFactors(), fileEncoding = "", encoding = "unknown", text, skipNul = FALSE)
Argumenty, z których sama najczęściej korzystam, to header, sep, row.names i col.names. Po kolei: header może być tylko wartością logiczną (TRUE / FALSE), i mówi R-owi o tym, czy pierwsza linia pliku to nagłówek. Domyślnie (jak widać) header jest ustawione na FALSE, czyli R uważa, że każdy wiersz to dane, a nazwy ma sobie sam wymyślić. Na przykład jeśli mój plik z danymi wyglądałby tak:
brutto netto
1234 1230
94.12 94
0.08 0.08
12 11.14
to wywołanie read.table() podając header = TRUE sprawi, że R zamiast domyślnych nazw V1 i V2 nazwie kolumny "brutto" i "netto":
> ( dane = read.table("plik_z_danymi", header=TRUE) ) brutto netto 1 1234.00 1230.00 2 94.12 94.00 3 0.08 0.08 4 12.00 11.14
Do kolumn, które mają nazwy możemy się odwoływać nie tylko indeksami, ale również ich nazwami:
> dane[,1] [1] 1234.00 94.12 0.08 12.00 > dane[,"brutto"] [1] 1234.00 94.12 0.08 12.00 > dane$brutto # nowy zapis! wiecej o tym w rozdziale o listach [1] 1234.00 94.12 0.08 12.00 > dane$"brutto" # moze byc z cudzyslowami, ale nie musi [1] 1234.00 94.12 0.08 12.00 > dane[,brutto] # a przy takim zapisie powinno byc w cudzyslowie Error in `[.data.frame`(dane, , brutto) : object 'brutto' not found
Kolejny argument, o którym wspomniałam, to "sep", czyli "separator", czyli coś, co oddziela kolejne kolumny. W moim pliku jest to tabulator; R domyślnie uważa, że separatorem będzie właśnie tabulator albo jakiś inny ciąg białych znaków. Jeśli mój plik wyglądałby tak:
1,2,3
4,5,6
dane wczytałyby się jako jedna kolumna z dwoma napisami: "1,2,3" i "4,5,6" zamiast z sześcioma liczbami:
> dane = read.table("plik_z_przecinkiem") > dane V1 1 1,2,3 2 4,5,6
Możemy to zmienić korzystając z argumentu sep i wprost mówiąc R-owi, że w naszym pliku kolumny oddzielone są przecinkiem:
> dane = read.table("plik_z_przecinkiem", sep=",") > dane V1 V2 V3 1 1 2 3 2 4 5 6
Kolejne argumenty, o których wspomniałam, to col.names i row.names, czyli argumenty pozwalające nadać kolumnom i wierszom nazwy. Mogą działać na przykład tak:
> oceny = read.table("plik_z_przecinkiem", sep=",", col.names = c("staszek","frania","genowefa"), row.names = c("historia", "matematyka")) > oceny staszek frania genowefa historia 1 2 3 matematyka 4 5 6
Można też zamiast wektora nazw podać liczbę, np. row.names = 1; wówczas R będzie wiedział, że to, co jest w pierwszej kolumnie to nazwy wierszy. Zauważmy, że podanie argumentu "col.names = 1" to to samo co podanie "header = TRUE".
Przykładowo, gdyby plik wyglądał tak:
biedronka;carrefour;sklepik_szkolny;produkt
1.10;2.05;;drozdzowka
2.20;2.50;3;woda gazowana
3.30;2.90;1.50;banany
moglibyśmy go wczytać tak:
> ( cennik = read.table("cennik", header = TRUE, row.names=4, sep = ";") ) biedronka carrefour sklepik_szkolny drozdzowka 1.1 2.05 NA woda gazowana 2.2 2.50 3.0 banany 3.3 2.90 1.5
Zauważmy, że nie ma w pliku danych o tym, po ile w sklepiku szkolnym są drożdżówki. R wpisał więc NA, czyli not available.