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):

> setwd("/home/maciosz/tmp/")
> getwd()
[1] "/home/maciosz/tmp"

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:

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:

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.