Ta strona wykorzystuje ciasteczka ("cookies") w celu zapewnienia maksymalnej wygody w korzystaniu z naszego serwisu. Czy wyrażasz na to zgodę?

Czytaj więcej
< All Topics
Print

Ramki, czyli tabele mające format baz danych

Tworzenie baz danych i nazywanie jej kolumn

Format zapisu danych, który dla biologów oznacza bazę danych, mają obiekty typu data.frame. Są to tabele złożone z jednakowej długości kolumn jednego typu danych odpowiadające zmiennym pomiarowym. Najczęściej są to wektory, szeregi czasowe i czynniki, ale czasami także macierze o odpowiedniej liczbie wierszy. Obiekty te tworzy się za pomocą funkcji data.frame().Wyniki pomiarów i eksperymentów w biologii mają często ten feler, że nie dla każdego obiektu uda się oznaczyć wartości wszystkich zmiennych. W bazach danych (nie tylko w R) istnieje zatem możliwość wprowadzania wartości pomijalnej. W R jest to NA. Większość programów pozwalająca na opracowanie baz danych pomija te wiersze i nie generuje błędu (np. przez wprowadzenie tam 0).

> plec.ciezar = data.frame(1:5, c("samica","samiec","samica",NA,"samiec"),
+ c(21,22,20.5,21,22.5))
> plec.ciezar
X1.5 c..samica....samiec....samica...NA...samiec.. c.21..22..20.5..21..22.5.
1  1                                        samica                     21.0
2  2                                        samiec                     22.0
3  3                                        samica                     20.5
4  4                                          <NA>                     21.0
5  5                                        samiec                     22.5

 

Nazywanie zmiennych, czyli kolumn w bazach danych, jest standardem. Gdy się tego nie zrobi programy komputerowe wprowadzają nazwy domyślne, a R robi to wyjątkowo złośliwie tworząc nazwę z wartości zmiennych. Należy zatem zawsze pamiętać o nazywaniu zmiennych.

> plec.ciezar = data.frame(1:5, plec=c("samica","samiec","samica",NA,"samiec"),
+ ciezar=c(21,22,20.5,21,22.5))
> plec.ciezar
  X1.5   plec ciezar
1    1 samica   21.0
2    2 samiec   22.0
3    3 samica   20.5
4    4   <NA>   21.0
5    5 samiec   22.5

 

Kiedy tworzymy bazę danych z obiektów (wektorów, szeregów czasowych, czynników), ich nazwy te stają się nazwami kolumn baz danych. Można je nazwać inaczej przez zastosowanie formuły: nazwa_kolumny=nazwa_obiektu.

> Nr=1:5
> plec=c("samica","samiec","samica",NA,"samiec")
> ciezar=c(21, 22,20.5,21,22.5)
> plec.ciezar=data.frame(Nr, plec, ciezar)
> plec.ciezar
  Nr   plec ciezar
1  1 samica   21.0
2  2 samiec   22.0
3  3 samica   20.5
4  4   <NA>   21.0
5  5 samiec   22.5
plec.ciezar=data.frame(NR=Nr,PLEC=plec,CIEZAR=ciezar)
> plec.ciezar
  NR   PLEC CIEZAR
1  1 samica   21.0
2  2 samiec   22.0
3  3 samica   20.5
4  4   <NA>   21.0
5  5 samiec   22.5

 

Baza danych wyświetla się zawsze z numeracją wierszy po lewej stronie. Wydaje się zatem, że numeracja osobników wprowadzana do bazy nie jest potrzebna. Jednak ta numeracja może być stosowana w dokumentacji pomiarów i wszelkie sortowania, filtrowania zaburzą porządek w tym ciągu, ale zostawią możliwość dotarcia do danych oryginalnych. Numeracja R nie jest związana z danymi – to aktualnie istniejący w bazie numer wiersza.

Po połączeniu za pomocą funkcji data.frame() wektorów, szeregów czasowych i czynników zachodzą następujące zmiany typów:

  • Wektor numeryczny zachowuje swój typ i kolumna przez niego tworzona jest wektorem numerycznym.
  • Wektor tekstowy zostaje zamieniony na czynnik, nawet wtedy, gdy traktowany jako wektor zajmowałby mniej miejsca.
  • Czynnik numeryczny lub tekstowy zachowuje swój typ.
  • Szereg czasowy zachowuje swój typ.

Najwygodniej to sprawdzić za pomocą funkcji str(), która pokazuje typ obiektu oraz typy poszczególnych kolumn.

> X=rep(1:2,13)
> Y=letters
> Z=ts(letters,200,frequency=12)
> XYZ=data.frame(X,Y,Z)
> str(XYZ)
'data.frame': 26 obs. of 3 variables:
$ X: int 1 2 1 2 1 2 1 2 1 2 ...
$ Y: Factor w/ 26 levels "a","b","c","d",..: 1 2 3 4 5 6 7 8 9 10 ...
$ Z: Time-Series from 200 to 202: a b c d ...
> XYZ=data.frame(as.factor(X),as.vector(Y),as.vector(Z))
> str(XYZ)
'data.frame': 26 obs. of 3 variables:
$ as.factor.X.: Factor w/ 2 levels "1","2": 1 2 1 2 1 2 1 2 1 2 ...
$ as.vector.Y.: Factor w/ 26 levels "a","b","c","d",..: 1 2 3 4 5 6 7 8 9 10 ...
$ as.vector.Z.: Factor w/ 26 levels "a","b","c","d",..: 1 2 3 4 5 6 7 8 9 10 ...

 

Specyficzną bazę danych tworzy funkcja expand.grid(). Funkcja ta służy do tworzenia tabeli z ciągów c1,c2,…,ck, tak że każdy element ciągu c2 jest w rzędzie z każdym elementem ciągu c1, każdy element ciągu c3 jest w rzędzie z każdą wcześniej wygenerowaną parą itd.

> expand.grid(letters[1:2],5:6,c(TRUE,FALSE))
  Var1 Var2  Var3
1    a    5  TRUE
2    b    5  TRUE
3    a    6  TRUE
4    b    6  TRUE
5    a    5 FALSE
6    b    5 FALSE
7    a    6 FALSE
8    b    6 FALSE
> expand.grid(letters[1:2],5:6,c(T,F))->tabela
> tabela[[1]]
[1] a b a b a b a b
Levels: a b
> tabela[[2]]
[1] 5 5 6 6 5 5 6 6
> tabela[[3]]
[1] TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE

 

Są sytuacje, gdy funkcja ta znacznie przyśpiesza utworzenie bazy danych, albo jej szkieletu. Przykładowo, gdy w kilku sezonach i lokalizacjach rozstawiono pułapki Barbera, a następnie oznaczono gatunki owadów, które złapały się do nich. Najlepiej jest wykonać funkcje expand.grid() dla ciągów oznaczających sezony, lokalizacje i wykaz gatunków. Potem można dodać kolumną z samymi zerami, która już ręcznie zostanie zmodyfikowana przez zastąpienie odpowiednich zer liczbą owadów danego gatunku złowionych w danym sezonie, w danej lokalizacji, o ile były tam takie owady. W takich bazach danych zera są także wynikiem.

Wczytywanie do R baz danych zapisanych w formacie tekstowym

Na ogół badacze posiadają własny podstawowy typ baz danych, w których przechowują komplet informacji o wykonanych doświadczeniach i obserwacjach. W takiej bazie danych wykonuje się wszelkie poprawki, uzupełnia o nowe obserwacje. Te bazy danych, często redukowane w celu opracowania tylko jednego zagadnienia, eksportuje się potem do innych programów zmieniając ich format, pozostawiając jednocześnie oryginał do dalszych analiz. W latach 90-tych podstawowe bazy danych przeważnie przechowywane były w formacie “dbf” (dbase), z czasem rozpowszechnił się Excel (na małe projekty) i Access (na duże bazy danych). Wynikało to z wygody tworzenia takich baz w tych programach, zwłaszcza gdy dane do nich przepisywano ręcznie z notatek. Czasy się zmieniają i obecnie w wielu dziedzinach biologii, chemii, fizyki i nauk środowiskowych stosuje się aparaturę zapisującą wyniki pomiarów na nośniki elektroniczne. Z reguły dane takie zapisywane są do plików tekstowych. Podstawową umiejętnością badacza stało się importowanie takich danych do różnych programów, łączenie w jedną bazę danych i przetwarzanie. Można obecnie twierdzić, że podstawowe dane przechowuje się w plikach tekstowych.

Pliki tekstowe tworzone automatycznie mają format bazy danych, z reguły pierwsza linijka przeznaczona jest na nazwy, a pod nią pojawiają się wartości dotyczące danego pomiaru. Przykładowo plik generowany przez aparaturę do pomiaru kierunku i prędkości wiatru produkuje następujący plik tekstowy:

Natomiast licznik przerywań notujący numer pomiaru, datę, godzinę, minutę i sekundę przechodzenia ptaka przez otwór budki lęgowej daje plik tekstowy:

Pliki tekstowe umieszcza się w katalogu zrobionym dla danego tematu badawczego. W tym folderze trzyma się tekstowe bazy danych, programy i zestawy instrukcji zapisane w plikach tekstowych wykonujące w R określone analizy oraz wyniki takich obliczeń. Katalog taki robi się samemu, a potem informuje R o jego nazwie i ścieżce dostępu, czyli zmienia w R katalog roboczy.

Jaki jest aktualny katalog roboczy odkrywa się za pomocą instrukcji getwd(), a ewentualną zmianę katalogu roboczego można określić za pomocą instrukcji setwd(“C:/….”). W nazwach katalogów stosuje się ukośniki “/”, także w systemie windows. Przykładowo, gdy pliki tekstowe znajdują się na pulpicie użytkownika “milka” można wykonać wybrane operacje pokazane poniżej.

Dla Windows XP

> # Windows XP
> getwd()
[1] "C:/Documents and Settings/Milka/Moje dokumenty"
> setwd("C:/Documents and Settings/milka/Desktop/...")

 

Dla Windows 7, 8, 10:

> # Windows 10
> getwd()
[1] "C:/Users/milka/Documents"
> setwd("C:/Users/milka/Desktop/...")

 

Zmiany katalogu roboczego można dokonać także metodą kliknięć. Najpierw należy wybrać “Plik”/”File”, potem “Zmień katalog”/”Change dir” i w okienku pokazanym poniżej dojść do wybranego katalogu roboczego i kliknąć OK/Zastosuj.

 

 

 

 

 

 

 

 

 

Jeżeli nie chcemy zmieniać katalogu roboczego a plik, który chcemy zaimportować, jest w innym miejscu, trzeba jego nazwę podać wraz z adresem (ścieżką dostępu), w którym stosowane będą ukośniki “/”.

Po wybraniu właściwego katalogu można sprawdzić, czy znajdują się w nim gotowe do transportu pliki tekstowe. Za pomocą funkcji list.files() uzyskamy listę nazw plików znajdujących się w katalogu roboczym.

> getwd()
[1] "C:/Users/milka/Downloads"
> list.files()
[1] "desktop.ini"
[2] "FileZilla_3.7.4.1_win32-setup.exe"
[3] "iview437_setup_www.INSTALKI.pl.exe"
[4] "PDFCreator-1_9_2-setup-beta.exe"
[5] "przerywania.txt"
[6] "wiatr.dat"

 

W pierwszej bazie separatorami były tabulatory, a w drugiej przecinki. Poszczególne obserwacje rozdzielone są znakiem końca wiersza. Dość często separatorami są średniki, spacje, ukośniki lub inne symbole widoczne na klawiaturze. Programy tekstowe mają różne rozszerzenia, najczęściej .txt lub .csv lub .dat lub .prn. Ich zaimportowanie do R polega na używaniu instrukcji read.table(“nazwa.txt”) z różnymi opcjami. Wystarczy przyjrzeć się przykładom.

> # Zaimportowanie pliku wiatr.dat, pokazanego na pierwszym rysunku
> wiatr=read.table("wiatr.dat", header=TRUE, sep="\t")
> wiatr
     date Dir Spd
1 1961071 360 7.2
2 1961072  10 7.7
3 1961072 360 9.3
4 1961072 360 9.3
5 1961073 360 8.7
6 1961073  30 7.2
7 1961073  20 7.2
8 1961074 110 1.5
> # zaimportowanie pliku przerywania.txt pokazanego na drugim rysunku
> przeryw=read.table("przerywania.txt", header=FALSE, sep=",")
> przeryw
  V1       V2       V3
1  1 14-04-12 09:58:13
2  2 14-04-12 10:10:52
3  3 14-04-12 10:23:31
4  4 14-04-12 10:28:47
5  5 14-04-12 10:44:11
6  6 14-04-12 10:51:07
7  7 14-04-12 11:00:28
8  8 14-04-12 11:05:22
9  9 14-04-12 11:28:37

 

Pod opcjami kryją się pewne wybrane wartości, które są przyjmowane automatycznie w sytuacji braku jakiejś opcji. Przykładowo za header podstawiana jest automatycznie wartość FALSE i w drugim przykładzie w ogóle nie trzeba pisać tej opcji. Za separatory podstawiana jest wartość “\t” (co oznacza tabulatory) i opcji tej nie trzeba pisać w pierwszym przykładzie.

> # Zaimportowanie pliku wiatr.dat, pokazanego na pierwszym rysunku
> wiatr=read.table("wiatr.dat", header=TRUE)
> wiatr
     date Dir Spd
1 1961071 360 7.2
2 1961072  10 7.7
3 1961072 360 9.3
4 1961072 360 9.3
5 1961073 360 8.7
6 1961073  30 7.2
7 1961073  20 7.2
8 1961074 110 1.5
> # zaimportowanie pliku przerywania.txt pokazanego na drugim rysunku
> przeryw=read.table("przerywania.txt", sep=",")
> przeryw
  V1       V2       V3
1  1 14-04-12 09:58:13
2  2 14-04-12 10:10:52
3  3 14-04-12 10:23:31
4  4 14-04-12 10:28:47
5  5 14-04-12 10:44:11
6  6 14-04-12 10:51:07
7  7 14-04-12 11:00:28
8  8 14-04-12 11:05:22
9  9 14-04-12 11:28:37

 

Lista opcji instrukcji read.table(“”) jest dość rozbudowana. Podajemy tylko najważniejsze.

  • header Pytanie, czy w pierwszej linijce są nagłówki mające wartości TRUE i FALSE, automatycznie FALSE.
  • sep Wskazanie separatora zmiennych, mający wartości będące symbolami znajdującymi się na klawiaturze zapisywane w “”. Automatycznie tabulator oznaczany dwuznakiem “\t”.
  • quote Wskazanie znaków, jakie w pliku tekstowym oznaczają zmienne tekstowe.
  • dec Wskazanie znaku stosowanego przy zapisie liczb dziesiętnych (, lub .).
  • row.names Zastąpienie standardowej pierwszej kolumny (kolejne liczby całkowite dodatnie) kolumną nazw wierszy.
  • col.names Zastąpienie standardowych nazw kolumn V1 V2,…,V3 podanym wektorem nazw.
  • nrrows Maksymalna liczba wierszy, jaka ma być zaimportowana.
  • skip Liczba wierszy, jaką na początku należy pominąć.

Wariantami funkcji read.table() są: read.csv(), read.csv2(), read.delim() i read.delim2(). Służą do przenoszenia danych zapisanych w sformatowanych plikach tekstowych. Ponadto nie robią one nic nowego, czego nie robiłaby funkcja read.table() z odpowiednimi opcjami.

Wykonywanie jakichkolwiek operacji na zaimportowanej bazie danych wymaga przypisania jej jakiemuś obiektowi. Trzeba koniecznie po ustaleniu właściwych opcji i poprawnym imporcie, wymyślić klarowną nazwę dla ramki danych i zastosować instrukcję przypisania.

> # Zaimportowanie pliku wiatr.dat, pokazanego na pierwszym rysunku
> read.table("wiatr.dat", header=TRUE)
     date Dir Spd
1 1961071 360 7.2
2 1961072  10 7.7
3 1961072 360 9.3
4 1961072 360 9.3
5 1961073 360 8.7
6 1961073  30 7.2
7 1961073  20 7.2
8 1961074 110 1.5
> read.table("wiatr.dat", header=TRUE)->wiatr

 

Oczywiście może być wiatr=read.table(…). Po imporcie danych trzeba koniecznie sprawdzić, czy dane numeryczne są rzeczywiście numeryczne. Najlepiej do tego nadaje się funkcja str().

> wiatr = read.table("wiatr.dat", header=TRUE)
> str(wiatr)
'data.frame': 8 obs. of 3 variables:
$ date: int 1961071 1961072 1961072 1961072 1961073 1961073 1961073 1961074
$ Dir : int 360 10 360 360 360 30 20 110
$ Spd : num 7.2 7.7 9.3 9.3 8.7 7.2 7.2 1.5

 

Gdyby przy kolumnie Spd (prędkość wiatru) pojawiła się informacja Spd : char lub Spd : factor oznaczyłoby to, że dane są źle zaimportowane. Może są przecinki w liczbach rzeczywistych, podczas gdy system wymaga kropek lub gdzieś pojawia się słowo brak lub inne tego typu wyrażenie nieliczbowe. Słowa te należy w pliku tekstowym zamienić na NA i ponownie wykonać funkcję read.data().

Importowanie baz danych z arkuszy kalkulacyjnych

Stosowanie funkcji data.frame() nie jest wygodnym sposobem na tworzenie bazy danych. Najpierw trzeba utworzyć zmienne wektorowe z danymi jednego typu pilnując kolejności ich wpisywania, by na każdym i-tym miejscu ciągu dane pochodziły z pomiarów i-tego obiektu. R nie ma możliwości skontrolowania, czy wyniki na trzecim miejscu w każdym ciągu pochodziły od tego samego eksperymentu czy zwierzęcia. Bardzo łatwo pomylić się w dopasowaniu wartości różnych zmiennych i uzyskać poprawny obiekt pod względem informatycznym, a dający błędne wyniki przy opracowaniu danych. Na szczęście można przenieść na raz wszystkie dane z innych programów, gdzie tworzenie baz danych jest dużo prostsze.

Arkusze kalkulacyjne (Excel, Open Office(arkusz kalkulacyjny) lub Libre Office4(Arkusz kalkulacyjny)) są znacznie wygodniejsze od R do tworzenia bazy danych. Konieczne jest zatem znalezienie prostego sposobu przeniesienia utworzonej już bazy danych np. z Excela do R. Tymczasem przejrzenie procedur wczytywania plików do R pokazuje, że prostej funkcji wykonującej taką operację, nie ma. Trzeba poradzić sobie metodą:

  • transportu danych do pliku tekstowego,
  • importu danych tekstowych do R.

Uniwersalna metoda jest dość pracochłonna i polega na:

  • Wykonaniu bazy danych w arkuszu kalkulacyjnym, w którym nie będzie pustych miejsc. Braki danych zastąpić słowem “NA”. Z kolumn tekstowych usunąć spacje lub zastąpić kropką lub podkreśleniem.
  • Nazwy kolumn wpisać w jednej linijce. Usunąć z nich spacje, przecinki, nawiasy i inne znaki, które nie mogą występować w nazwach obiektów R (patrz rozdział “Instrukcja przypisania i obiekty”, podrozdział “Literały”)
  • Zaznaczeniu całej bazy danych i przeniesienie zaznaczonej zawartości do schowka przez wciśnięcie Ctrl+C.
  • Utworzeniu z katalogu roboczym pustego pliku tekstowego (z rozszerzeniem .txt). Nazwanie go.
  • Otworzenie pliku tekstowego i skopiowanie do niego zawartości schowka (wciśnięcie Ctrl_V).
  • Zamiana w pliku tekstowym separatorów w liczbach dziesiętnych “,” na “.” (Zamień/zastąp “,” na “.” wszędzie/cały dokument itd.).
  • Zapamiętaniu.
  • Otworzeniu R
  • Zmianę katalogu R na odpowiedni katalog roboczy, gdzie znajduje się wykonany plik tekstowy.
  • Sprawdzeniu, czy pracujemy we właściwym katalogu. Najwygodniej jest to wykonać za pomocą funkcji list.files(), w której nie wpisujemy żadnego argumentu, a która powoduje wyświetlenie wszystkich plików w katalogu roboczym. Jeżeli jest tam nazwa zrobionego właśnie pliku tekstowego – dobrze.
  • Wykonaniu funkcji read.table(“nazwa.pliku.tekstowego.txt”, header=TRUE).
  • Gdy obraz danych po wykonaniu takiej instrukcji wygląda na bazę danych, zapisaniu go jako obiektu R, czyli wykonaniu przypisania wyniku funkcji read.table(“nazwa.pliku.tekstowego.txt”, header=TRUE) jakiemuś obiektowi o odpowiedniej nazwie.
  • Sprawdzeniu czy utworzony obiekt ma właściwą strukturę przez wykonanie funkcji str(nazwa obiektu). Jeżeli kolumny liczbowe mają typ “num” lub “int” – dobrze. Jeżeli nie, w pierwszej kolejności sprawdzić plik tekstowy: czy nie ma tam separatorów “,” w liczbach, czy w tym ciągu kolumn nie pojawia się gdzieś jakiś tekst, znak nieliczbowy, podwójna kropka, słowo “Brak” zamiast NA itd. Poprawić, zapisać. Funkcję read.table() i przypisanie jej obiektowi, wykonać ponownie.
  • Po uzyskaniu poprawnej bazy danych, wykonaniu save.image(“Nazwa_wejścia_do_R.RData”), gdzie za Nazwę_wejścia_do_R należy wstawić swoją nazwę. W katalogu roboczym powinna pojawić się odpowiednia ikonka R z wprowadzoną nazwą. Wykonana baza danych będzie w niej zapamiętana, jako obiekt o wprowadzonej nazwie.

Opisana metoda polega na edycji baz danych zarówno w arkuszu kalkulacyjnym, jak i pliku tekstowym, pod katem ich prawidłowego przeczytania przez funkcję read.table() opisaną szczegółowo w poprzednim podrozdziale. Sprawdza się dla nie bardzo dużych baz danych z niewielką liczbą kolumn.

Niekiedy zależy nam na zachowaniu spacji w kolumnach tekstowych (ale spacji zawsze nie może być w nazwach kolumn). W zależności od wersji systemu i programu tworzącego arkusz jedne metody są lepsze inne gorsze. Trzeba popróbować by wybrać najlepszą. Poniżej podane są najczęściej publikowane przepisy.

Windows XP/Excel, OpenOffice.Calc i LibreOffice.Calc

  • Otworzyć arkusz kalkulacyjny z bazą danych. Powinna ona znajdywać się cała w jednym arkuszu. Usunąć zbędne tabele, wykresy, posumowania (ewentualnie skopiować samą bazę danych do nowego arkusza).
  • W miejsca braków danych (puste całe komórki) wpisać (kazać wpisać poprzez edytor) NA
  • Zapamiętać plik jako “nazwa.csv” w swoim katalogu roboczym. Za nazwę wybrać możliwie prosty tekst, bo będzie on później ręcznie wpisywany do R.
  • Zgodzić się na “Ostrzeżenie o zapisaniu tylko jednego arkusza w wybranym formacie”.
  • Potwierdzić gotowość zapisu.
  • Zamknąć arkusz kalkulacyjny nie zapisując zmian w bazie danych (ważne!!!).
  • Znaleźć plik “nazwa.csv”.
  • Otworzyć go przez Notatnik i wyrzucić wszelkie niepotrzebne znaki. Ma zostać tylko baza danych z nazwanymi kolumnami, przy czym nazwy kolumn są prawidłowymi literałami jako nazwy obiektów w R (patrz rozdział “Instrukcja przypisania i obiekty”, podrozdział “Literały”)
  • Zapamiętać plik nazwa.csv.

Otworzyć R. Przejść do katalogu, gdzie znajduje się zbiór “nazwa.csv”. Jego transport do R wymaga zastosowania jednej z funkcji read.csv(), read.csv2(), read.delim(), read.delim2(), albo opisaną w poprzednim podrozdziale funkcję read.table() z opcjami. Pojawia się czasem problem z polskojęzycznym systemem Windows. Czasami pokazuje on separatory “,” podczas gdy R widzi “;” oraz znaki liczb dziesiętnym “,” podczas gdy R widzi “.”. W XP jest mniej takich problemów i generalnie jeżeli w pliku “nazwa.csv” rozdzielnikami kolumn były przecinki stosujemy funkcję read.csv(), a jeżeli rozdzielnikami były średniki stosujemy funkcję read.csv2()

> read.csv2("nazwa.csv")
Nr;PLEC;SEZON;CIEZAR;FLUOR
1 1;samica;jesień;2.7;26.5
2 2;samica;jesień;4.1;26.0
3 3;samiec;zima;3.6;36.0
4 4;samica;wiosna;3;24.7
5 5;samica;jesień;4;25.9
6 6;samiec;zima;3.4;37.1
7 7;samiec;wiosna;2.6;30.2
8 8;samiec;zima;3.2;36.6
9 9;samiec;wiosna;3.6;295
10 10;samica;zima;3.4;31.0
... 
> # jeżeli zobaczyliśmy powyższą tabelę to wracamy do wpisywania danych do "nowanazwa" z użycie read.csv2
> read.csv2("nazwa.csv")
   Nr   PLEC  SEZON CIEZAR FLUOR
1   1 samica jesień    2.7 26.5
2   2 samica jesień    4.1 26.0
3   3 samiec   zima    3.6 36.0
4   4 samica wiosna      3 24.7
5   5 samica jesień      4 25.9
6   6 samiec   zima    3.4 37.1
7   7 samiec wiosna    2.6 30.2
8   8 samiec   zima    3.2 36.6
9   9 samiec wiosna    3.6 29.5
10 10 samica   zima    3.4 31.0
...
> # tę tabelę przypisujemy jakiemuś obiektowi.
> skunks=read.csv2("nazwa.csv")

 

Ostatni obraz jest typowy dla poprawnej ramki danych. Można ją sprawdzić np. funkcją str(), czy dane numeryczne są rzeczywiście numeryczne, kolumny prawidłowo nazwane itp.

Windows 7, 8 i 10/Excel, OpenOffice.Calc i LibreOffice.Calc

  • Utworzyć na pulpicie/własnym katalogu plik tekstowy o własnej nazwie, np. “nazwa.txt”
  • Otworzyć plik excelowy przez Excela, lub LbreOffice.calc z bazą danych.
  • W miejsca braków danych (puste całe komórki) wpisać (kazać wpisać) NA
  • Zaznaczyć bazę danych wraz z nagłówkami kolumn i przenieść ją do pamięci systemowej klikając na Ctrl+C.
  • Otworzyć przygotowany plik tekstowy i skopiować bazę danych klikając Ctrl+V.
  • Poprawić bazę danych tak by uniknąć konfliktów przy jej imporcie do R
    • – zamienić przecinki w liczbach dziesiętnych na kropki używając w “edytuj” polecenia “zamień” (czasem “znajdź/zamień”) i stosując zamień wszystko,
    • – zamienić niewidoczne pauzy na “_” także używając etytuj-zamień-zamień wszystko,
    • – sprawdzić, czy nie pojawiły się w tekście niepotrzebne znaki, zmiany porządku w tekście, czy nazw kolumn jest tyle samo co kolumn, czy każdy wiersz składa się z takiej samej liczby kolumn, Błędy usuwamy ręcznie lub, gdy jest ich więcej, stosując automatyczne polecenia.
  • Zapamiętać.

Przejść do R. Zmienić katalog na ten, w którym jest plik tekstowy. Można sprawdzić poleceniem list.files() czy w katalogu roboczym jest wasz plik tekstowy. Zastosować polecenie read.table() z opcją header=TRUE.

> read.table("nazwa.txt")
    V1    V2      V3     V4  V5
1   Nr  PLEC   SEZON CIEZAR FLUOR
2   1 samica jesień    2.7 26.06
3   2 samica jesień    4.1 26.0
4   3 samiec   zima    5.6 36.0
5   4 samica wiosna      3 24.7
6   5 samica jesień      8 25.9
7   6 samiec   zima    3.4 37.1
8   7 samiec wiosna    2.6 30.2
9   8 samiec   zima    3.2 36.6
10  9 samiec wiosna    3.6 29.5
11 10 samica   zima    3.4 31.0
...
> # Nagłówki kolumn zostały potraktowane jako wartości i wszystkie dane są typu "character".
> read.table("nazwa.txt", header=TRUE)
   Nr   PLEC   SEZON CIEZAR FLUOR
1   1 samica jesień    2.7 26.5
2   2 samica jesień    4.1 26.0
3   3 samiec   zima    3.6 36.0
4   4 samica wiosna      3 24.7
5   5 samica jesień      4 25.9
6   6 samiec   zima    3.4 37.1
7   7 samiec wiosna    2.6 30.2
8   8 samiec   zima    3.2 36.6
9   9 samiec wiosna    3.6 29.5
10 10 samica   zima    3.4 31.0
...
> # tę tabelę przypisujemy jakiemuś obiektowi.
> skunks=read.table("nazwa.txt", header=TRUE)

 

W pliku tekstowym zrobionym metodą Ctrl+C (dla danych z Excela), Ctrl+V (w pliku tekstowym) separatorami kolumn są tabulatory. Jest to wartość domyślna dla opcji sep=””. Gdy nie wychodzi prawidłowa ramka danych trzeba tę opcję dodać (sep=”\t”). Gdy liczby są typu character można dodać opcję dec=”.” albo dec=”,” i sprawdzić czy to poprawia transport danych.

> read.table("nazwa.txt", header=TRUE, sep="\t", dec=",")

 

Większość tych kłopotów wynika stąd, że w tłumaczonych na język polski niektórych wersjach systemu windows inne znaki i nazwy wyświetlane są na ekranie, a inne widzi R.

Po pozornie poprawnym zaimportowaniu bazy danych sprawdzamy ją stosując funkcję str().

> str(skunks)
'data.frame': 50 obs. of 5 variables:
$ Nr    : int 1 2 5 14 32 39 44 4 24 28 ...
$ PLEC  : Factor w/ 2 levels "samica","samiec": 1 1 1 1 1 1 1 1 1 1 ...
$ SEZON : Factor w/ 3 levels "jesień","wiosna",..: 1 1 1 1 1 1 1 $
$ CIEZAR: num 2.7 4.1 4 3.1 3.9 3.3 3.7 3 3.5 4 ...
$ FLUOR : num 26.2 24.7 24.3 28.1 26.4 ...

 

Zwracamy uwagę czy typy zmiennych są prawidłowe. Kolumny tekstowe w bazach danych są zapisem zmiennej dyskretnej mając często tylko 2 lub 3 lub nieco więcej wartości. Zmienne te zostały potraktowane, jako czynniki (factor) i najczęściej jest to prawidłowe. Zapis takich czynników został skrócony przez przypisanie nazwom liczb i wartości zapisane są w postaci liczb.

Dopiero gdy uzyskamy prawidłową ramkę danych zapisujemy obszar roboczy lub stosujemy funkcję save.image(“nazwa.RData”) do stworzenia “własnego wejścia do R”, w którym utworzony obiekt zostanie zapamiętany.

Bazy danych zaimplementowane do R

Do R zaimplementowano 104 obiekty z danymi, z czego ponad połowa ma format bazy danych. Można je zobaczyć na stronie: http://127.0.0.1:25589/library/datasets/html/datasets-package.html, do której można przejść wpisując do konsoli R ?datasets. Na stronie należy kliknąć na “index”. Wyświetli się lista nazw obiektów z krótkim opisem. Nazwy są linkami do stron z nieco szerszym opisem. Sam obiekt zobaczymy wpisując jego nazwę (bez literówek i uwzględniając wielkość liter) do konsoli R. Poniżej podano tylko pierwszych 6 wierszy wybranych baz danych.

Niektóre z zaimplementowanych do R baz danych zyskały sobie miano “kultowych” wśród użytkowników R. Są bowiem na ich przykładzie opisane różne procedury graficzne i statystyczne publikowane w podręcznikach internetowych i drukowanych. Do najbardziej znanych należy baza iris pokazująca długość i szerokość działek kielicha i płatków kwiatów 150 irysów zaliczonych do trzech gatunków. Została ona opublikowana przez R. Fishera i od lat służy studentom dla nauki statystyki (zwłaszcza wykonywania testów wieloczynnikowych). Doczekała się nawet własnej strony na angielskojęzycznej Wikipedii.

> head(iris)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

 

Drugą tego typu bazą jest ToothGrowth zawierająca dane o długości zębów kawii domowych (świnek morskich) w zależności od dawki witaminy C i sposobu jej dozowania (kwas askorbinowy, sok pomarańczowy).

> head(ToothGrowth)
    len supp dose
1   4.2   VC  0.5
2  11.5   VC  0.5
3   7.3   VC  0.5
4   5.8   VC  0.5
5   6.4   VC  0.5
6  10.0   VC  0.5

 

Ciekawą baza danych jest quakes charakteryzująca trzęsienia ziemi na Fidżi od 1964. Jej zmiennymi jest długość i szerokość geograficzna, głębokość, skala Richtera oraz liczba stacji rejestrująca to trzęsienie.

> head(quakes)
     lat   long depth mag stations
1 -20.42 181.62   562 4.8       41
2 -20.62 181.03   650 4.2       15
3 -26.00 184.10    42 5.4       43
4 -17.97 181.66   626 4.1       19
5 -20.42 181.96   649 4.0       11
6 -19.68 184.31   195 4.0       12

 

Prostszych i bardziej skomplikowanych baz danych jest w R około 50. Są wykorzystywane w przykładach zastosowania różnych funkcji w R w pliku pomocy. Przykładowo, bazy InsectSprays i OrchardSprays zostały wykorzystane do zobrazowania możliwości funkcji graficznej boxplot()

Odwołania do elementów baz danych

Każdy element bazy danych ma swoją pozycję (nr wiersza i nr kolumny) i wyświetlenie go polega na napisaniu w konsoli nazwa.bazy[i,j], gdzie i jest numerem wiersza, j numerem kolumny. Poprzez indeksowanie baza[c(i1,i2,i3,…in),c(j1,j2,…,jk)] uzyskuje się podtabelę złożoną tylko z części wierszy i kolumn. Dodanie znaku – przed c eliminuje z bazy wymienione wiersze lub kolumny.

> skunks
    PLEC  SEZON CIEZAR     F
1 samica jesień    2.7 26.51
2 samica jesień    4.1 26.06
3 samiec   zima    3.6 36.02
4 samica wiosna    3.0 24.78
5 samica jesień    4.5 25.97
> skunks[c(1,3,5),c(1,3,4)]
    PLEC CIEZAR FLUOR
1 samica    2.7 26.51
3 samiec    3.6 36.02
5 samica    4.5 25.97
> skunks[-c(1,3,5),c(1,3,4)]
    PLEC CIEZAR FLUOR
2 samica    4.1 26.06
4 samica    3.0 24.78
> skunks[c(1,3,5),-c(1,3,4)]
[1] jesień zima   jesień
Levels: jesień wiosna zima

 

Dopuszczalna jest także składnia baza[,2:4] (wszystkie wiersze i 3 ostatnie kolumny) oraz baza[1:3,] (trzy pierwsze wiersze i wszystkie kolumny). Przykładowo baza[c(1:3,5),] oznacza wszystko bez czwartego wiersza.

Zastosowanie składni baza[n] powoduje pokazanie n-tej kolumny. Natomiast składnia baza[[n]] oraz baza[,n] spowodują pokazanie wartości n-tej kolumny w postaci wektora lub czynnika.

> skunks
    PLEC  SEZON CIEZAR     F
1 samica jesień    2.7 26.51
2 samica jesień    4.1 26.06
3 samiec   zima    3.6 36.02
4 samica wiosna    3.0 24.78
5 samica jesień    4.5 25.97
> skunks[2]
    SEZON
1 jesień
2 jesień
3   zima
4 wiosna
5 jesień
> skunks[[2]]
[1] jesień jesień zima   wiosna jesień
Levels: jesień wiosna zima
> skunks[,2]
[1] jesień jesień zima   wiosna jesień
Levels: jesień wiosna zima

 

Innym sposobem odwołania się do kolumny o danej nazwie (np. “PLEC”) jest składnia “nazwa bazy”$”nazwa kolumny” (np. skunks$PLEC).

> skunks
    PLEC  SEZON CIEZAR     F
1 samica jesień    2.7 26.51
2 samica jesień    4.1 26.06
3 samiec   zima    3.6 36.02
4 samica wiosna    3.0 24.78
5 samica jesień    4.5 25.97
> skunks$PLEC
 [1] samica samica samiec samica samica
Levels: samica samiec

 

Edycja baz danych

Zmiany wartości komórek w bazach danych wykonuje się przez zwykłe przypisanie określonej komórce nowej wartości.

> skunks
    PLEC  SEZON CIEZAR     F
1 samica jesień    2.7 26.51
2 samica jesień    4.1 26.06
3 samiec   zima    3.6 36.02
4 samica wiosna    3.0 24.78
5 samica jesień    4.5 25.97
> skunks[1,4]=20.0
> skunks[[4]][2]=300
> skunks$FLUOR[4]=400
> skunks
    PLEC  SEZON CIEZAR     F
1 samica jesień    2.7 20.00
2 samica jesień    4.1 30.00
3 samiec   zima    3.6 36.02
4 samica wiosna    3.0 24.78
5 samica jesień    4.5 40.00

 

W bazach danych kolumny z danymi tekstowymi są obiektami o typie czynnikowym (factor). Mają one z góry ustaloną liczbę wartości, co powoduje niemożność edycji związanej z wprowadzaniem nowych. Gdy zaistnieje potrzeba wprowadzenia nowej wartości trzeba usupełnić o nią wektor tekstowy levels(nazwa_bazy$nazwa_czynnika).

> skunks
    PLEC  SEZON CIEZAR     F
1 samica jesień    2.7 26.51
2 samica jesień    4.1 26.06
3 samiec   zima    3.6 36.02
4 samica wiosna    3.0 24.78
5 samica jesień    4.5 25.97
> skunks$PLEC[1]="samica ciezarna"
Komunikat ostrzegawczy:
In `[<-.factor`(`*tmp*`, 2, value = c(2L, NA, 2L, 1L, 1L)) :
invalid factor level, NA generated
> skunks
    PLEC  SEZON CIEZAR     F
1   <NA> jesień    2.7 26.51
2 samica jesień    4.1 26.06
3 samiec   zima    3.6 36.02
4 samica wiosna    3.0 24.78
5 samica jesień    4.5 25.97
> levels(skunks$PLEC)=c(levels(skunks$PLEC),"samica ciezarna")
> skunks$PLEC[1]="samica ciezarna"
> skunks
            PLEC  SEZON CIEZAR FLUOR
1 samica ciezarna jesień    2.7 26.5.1
2          samica jesień    4.1 26.06
3          samiec   zima    3.6 36.02
4          samica wiosna    3.0 24.78
5          samica jesień    4.5 25.97

 

Wiele osób lubi modyfikować bazy danych wtedy gdy je widzi, to znaczy ogląda ich wartości w tabeli, a jednocześnie może je zmieniać. R umożliwia to za pomocą funkcji fix(). Baza danych wyświetla się w następującej postaci:

Poprzez dwukrotne kliknięcie na poszczególne pola tej tabeli można dokonać zmian wartości zmiennych. Zmiany są pamiętane od razu, bez potrzeby ich potwierdzenia. Jednocześnie nie ma możliwości powrotu do poprzednich wartości. Po naciśnięciu na × w prawym górnym rogu wracamy do konsoli R. Nowe wartości już tkwią w obiekcie. W tabeli, którą pokazuje funkcja fix(), można wprowadzać nowe wartości do zmiennych czynnikowych. Po zamknięciu tej tabeli automatycznie przypisane one zostaną czynnikom, choć pojawi się przy tym komunikat:

Komunikat ostrzegawczy:
W poleceniu ‘edit.data.frame(get(subx, envir = parent), title = subx, …)’:
dodane poziomy czynnika w ‘nazwa zmiennej’

Łączenie baz danych

Łączenie tabel można rozpatrywać jako dołączanie kolumn z jednej tabeli do drugiej (łączenie poziome) lub dołączanie wierszy do tabeli (łączenie pionowe). W pierwszym wypadku dołączamy kolumny o takiej samej długości jak liczba wierszy w pierwszej tabeli. Przy łączeniu pionowym poszczególne bazy danych muszą zgadzać się liczbą, typami, a także nazwami poszczególnych kolumn, choć mogą mieć różne liczby wierszy. Jest jeszcze przypadek dołączania dodatkowych informacji do poszczególnych wierszy w pierwszej bazie, które są zawarte w drugiej bazie. Obie bazy muszą posiadać kolumnę o tej samej nazwie i wartościami, która stanowić będzie klucz do kolejności dołączania nowych informacji w dodatkowych kolumnach. Jest to łączenia baz danych wg klucza.

Pionowe łączenie baz danych

Dodanie nowej kolumny odbywa się najczęściej poprzez funkcję cbind(). Dodawany wektor lub czynnik powinien mieć taką samą długość jak liczba wierszy w bazie danych.

> skunks
    PLEC  SEZON CIEZAR FLUOR
1 samica jesień    2.7 26.51
2 samica jesień    4.1 26.06
3 samiec   zima    3.6 36.02
4 samica wiosna    3.0 24.78
5 samica jesień    4.5 25.97
> cbind(Nr=1:7,skunks)
Błąd w poleceniu 'data.frame(..., check.names = FALSE)':
argumenty sugerują różną liczbę wierszy: 7, 5
> cbind(Nr=1:4,skunks)
Błąd w poleceniu 'data.frame(..., check.names = FALSE)':
argumenty sugerują różną liczbę wierszy: 4, 5
> skunks=cbind(Nr=1:5,skunks)
> skunks
> skunks
 Nr   PLEC  SEZON CIEZAR FLUOR
1 1 samica jesień    2.7 26.51
2 2 samica jesień    4.1 26.06
3 3 samiec   zima    3.6 36.02
4 4 samica wiosna    3.0 24.78
5 5 samica jesień    4.5 25.97

 

Funcja cbind() umożliwia także poziome łączenie baz danych, o ile mają one taką samą liczbę wierszy.

Usunięcie kolumny odbywa się poprzez odwołanie się do części, które chcemy zostawić i przypisanie ich nowemu obiektowi. Generalnie obiektowi temu daje się nową nazwę, bo do usuniętych danych, nie zapamiętanych pod inną nazwą, nie można już powrócić.

> skunks
    PLEC  SEZON CIEZAR FLUOR
1 samica jesień    2.7 26.51
2 samica jesień    4.1 26.06
3 samiec   zima    3.6 36.02
4 samica wiosna    3.0 24.78
5 samica jesień    4.5 25.97
> skunks1=skunks[,1:3]
> skunks1
    PLEC  SEZON CIEZAR
1 samica jesień    2.7
2 samica jesień    4.1
3 samiec   zima    3.6
4 samica wiosna    3.0
5 samica jesień    4.5
> skunks2=skunks[,-4]
> skunks2
    PLEC  SEZON CIEZAR
1 samica jesień    2.7
2 samica jesień    4.1
3 samiec   zima    3.6
4 samica wiosna    3.0
5 samica jesień    4.5

 

Poziome łączenie baz danych

Do poziomego łączenia różnych baz danych, ale mających przynajmniej po jednej kolumnie opisującej te same obiekty biologiczne pod tymi samymi nazwami, w taki sposób, by w wyniku uzyskać bazę danych

Do dodawania nowych wierszy służy funkcja rbind(). Dodawany wiersz powinien być jednolinijkowym obiektem data.frame, albo listą o typach poszczególnych elementów takich samych jak typy kolumn wyjściowej bazy danych. Dołączanie danych w postaci wektora z reguły generuje błędy.

> skunks
    PLEC  SEZON CIEZAR FLUOR
1 samica jesień    2.7 26.51
2 samica jesień    4.1 26.06
3 samiec   zima    3.6 36.02
4 samica wiosna    3.0 24.78
5 samica jesień    4.5 25.97
> skunks1=rbind(skunks,1:4)
> skunks1
    PLEC  SEZON CIEZAR FLUOR
1 samica jesień    2.7 26.51
2 samica jesień    4.1 26.06
3 samiec   zima    3.6 36.02
4 samica wiosna    3.0 24.78
5 samica jesień    4.5 25.97
6   <NA>   <NA>    3.0 40
Komunikaty ostrzegawcze:
1: W poleceniu '`[<-.factor`(`*tmp*`, ri, value = 1L)':
niepoprawny poziom czynnika, wygenerowano wartość NA
2: W poleceniu '`[<-.factor`(`*tmp*`, ri, value = 2L)':
niepoprawny poziom czynnika, wygenerowano wartość NA
> skunks2=rbind(skunks,c("samiec","wiosna",3,40))
> skunks2
    PLEC  SEZON CIEZAR FLUOR
1 samica jesień    2.7 26.51
2 samica jesień    4.1 26.06
3 samiec   zima    3.6 36.02
4 samica wiosna    3.0 24.78
5 samica jesień    4.5 25.97
6 samiec wiosna      3 40
> str(skunks2)
'data.frame':   5 obs. of  4 variables:
$ PLEC  : Factor w/ 2 levels "samica","samiec": 1 1 2 1 1 2
$ SEZON : Factor w/ 3 levels "jesień","wiosna",..: 1 1 3 2 1 2
$ CIEZAR: chr "2.7" "4.1" "3.6" "3" ...
$ FLUOR : chr "26.51" "26.06" "36.02" "24.78" ...
> skunks3=rbind(skunks,list("samiec","wiosna",3,400))
> skunks3
    PLEC  SEZON CIEZAR FLUOR
1 samica jesień    2.7 26.51
2 samica jesień    4.1 26.06
3 samiec   zima    3.6 36.02
4 samica wiosna    3.0 24.78
5 samica jesień    4.5 25.97
6 samiec wiosna    3.0 40.00
> str(skunks2)
'data.frame':   5 obs. of  4 variables:
$ PLEC  : Factor w/ 2 levels "samica","samiec": 1 1 2 1 1 2
$ SEZON : Factor w/ 3 levels "jesień","wiosna",..: 1 1 3 2 1 2
$ CIEZAR: num 2.7 4.1 3.6 3 4.5 3
$ FLUOR : num 26.51 26.06 36.02 24.78 25.97 ...

 

Dołączane wektory, to elementy jednego typu. Gdy występują w nich teksty i liczby, wszystkie elementy traktowane są jako dane tekstowe. Dołączenie choć jednego elementu tekstowego do danych numerycznych zmienia typ całej kolumny.

Funkcja rbind() służy także do pionowego łączenia baz danych mających takie same liczby i nazwy kolumn. Jednak gdy dołącza się kolumnę tekstową do kolumny numerycznej całość staje się czynnikiem o wartościach tekstowych.

> skunks1
    PLEC  SEZON CIEZAR
1 samica jesień    2.7
2 samica jesień    4.1
3 samiec   zima    3.6
4 samica wiosna    3.0
5 samica jesień    4.5
> skunks2
    PLEC  SEZON FLUOR
1 samica jesień    26.51
2 samica jesień    26.06
3 samiec   zima    36.02
4 samica wiosna    24.78
5 samica jesień    25.97
> rbind(skunks1,skunks2)
Błąd w poleceniu 'match.names(clabs, names(xi))':
nazwy nie zgadzają się z poprzednimi nazwami
> names(skunks2)[3]="CIEZAR"
> skunks2
    PLEC  SEZON CIEZAR
1 samica jesień    26.51
2 samica jesień    26.06
3 samiec   zima    36.02
4 samica wiosna    24.78
5 samica jesień    25.97
> rbind(skunks1,skunks2)
     PLEC  SEZON CIEZAR
1  samica jesień    2.7
2  samica jesień    4.1
3  samiec   zima    3.6
4  samica wiosna    3.0
5  samica jesień    4.5
6  samica jesień  26.51
7  samica jesień  26.06
8  samiec   zima  36.02
9  samica wiosna  24.78
10 samica jesień  25.97

 

Łączenie baz danych wg klucza

Dość często wartościom pewnych czynników odpowiadają różne charakterystyki ułożone w inne bazy danych. Gdybyśmy chcieli je dołączyć do naszej bazy danych musielibyśmy to zrobić tak, by charakterystyki pasowały do kolejnych obiektów biologicznych, a więc dla danego wiersza z pierwszej bazy wybierany powinien być ten wiersz z drugiej bazy, który ma odpowiednią wartość charakteryzowanego czynnika. Służy do tego funkcja merge() z opcją by=”nazwa czynnika”.

> skunks
    PLEC  SEZON CIEZAR     F
1 samica jesień    2.7 26.51
2 samica jesień    4.1 26.06
3 samiec   zima    3.6 36.02
4 samica wiosna    3.0 24.78
5 samica jesień    4.5 25.97
> pogoda
   SEZON TEMP OPAD
1 wiosna 17.3   23
2 jesień 18.2   43
3   zima  4.5   53
> merge(skunks, pogoda, by="SEZON")
   SEZON   PLEC CIEZAR FLUOR TEMP OPAD
1 jesień samica    2.7 26.51 18.2   43
2 jesień samica    4.1 260.6 18.2   43
3 jesień samica    4.5 259.7 18.2   43
4 wiosna samica    3.0 247.8 17.3   23
5   zima samiec    3.6 360.2  4.5   53

 

W R nie ma możliwości tworzenia relacji wg. klucza między poszczególnymi bazami danych, ale dla większości zastosowań ich łączenie wg. klucza jest zupełnie wystarczające w badaniach biologicznych. Problem mogą sprawiać tylko bardzo długie bazy danych, bo po ich połączeniu powstaje nowa ogromna baza danych zajmująca bardzo dużo miejsca i pamięci. W takich przypadkach lepiej jest zrezygnować z R i pracować w odpowiednich programach typu Access lub bazy danych w Libre Office.

Filtrowanie baz danych

zobaczenie wybranych wierszy możliwe jest przez ich wskazanie: nowa.nazwa.bazy=nazwa.bazy[c(1,3:5),] lub nowa.nazwa.bazy=nazwa.bazy[-2,]. W praktyce jednak najczęściej usuwa się wiersze dla których wartość wybranej zmiennej nie odpowiada określonym kryteriom. Zarówno wybór wierszy jak i usunięcie według kryterium logicznego można zrealizować funkcją subset(nazwa.bazy, kryterium)

> skunks
    PLEC  SEZON CIEZAR FLUOR
1 samica jesień    2.7 26.51
2 samica jesień    4.1 26.06
3 samiec   zima    3.6 36.02
4 samica wiosna    3.0 24.78
5 samica jesień    4.5 25.97
> skunks1=subset(skunks,FLUOR>26.0)
> skunks1
    PLEC  SEZON CIEZAR FLUOR
1 samica jesień    2.7 26.51
2 samica jesień    4.1 26.06
3 samiec   zima    3.6 36.02

 

Standardowo do podbazy danych przechodzą wszystkie kolumny. Czasami trzeba wybrać ich tylko kilka i do tego celu służy opcja select=c(nazwa.kolumny1,nazwa.kolumny2,…). Zastosowanie znaku – przed ciągiem nazw zmiennych w opcji select powoduje, że wymienione w nim kolumny zostaną usunięte.

> skunks
    PLEC  SEZON CIEZAR FLUOR
1 samica jesień    2.7 26.51
2 samica jesień    4.1 26.06
3 samiec   zima    3.6 36.02
4 samica wiosna    3.0 24.78
5 samica jesień    4.5 25.97
> skunks1=subset(skunks,FLUOR>26,select=c(CIEZAR,FLUOR))
> skunks1
  CIEZAR FLUOR
1    2.7 26.5.1
2    4.1 260.6
3    3.6 360.2
> skunks2=subset(skunks,FLUOR>26,select=-c(PLEC,SEZON))
> skunks2
  CIEZAR FLUOR
1    2.7 26.51
2    4.1 26.06
3    3.6 36.02

 

Sortowanie baz danych

Zobaczenie wierszy w innej kolejności, niż jest to określone w bazie danych możliwe jest przez użycie formuły baza[c(3,2,5,4,…),], gdzie ciąg widoczny wewnątrz jest pewną permutacją liczb 1:n, gdzie n jest liczbą wierszy w bazie. Z rozdziału o wektorach i czynnikach wiadomo, że funkcja order() pokazuje ciąg liczb oznaczających miejsca wartości ciągu lub czynnika uporządkowanych liczbowo albo alfabetycznie. oznacza to, że baza[order(nazwa.kolumny),] pokaże się, jako posortowana względem wartości wybranej kolumny.

> skunks
    PLEC  SEZON CIEZAR FLUOR
1 samica jesień    2.7 26.51
2 samica jesień    4.1 26.06
3 samiec   zima    3.6 36.02
4 samica wiosna    3.0 24.78
5 samica jesień    4.5 25.97
> skunks[c(3,5,1,4,2),]
    PLEC  SEZON CIEZAR FLUOR
3 samiec   zima    3.6 36.02
5 samica jesień    4.5 25.97
1 samica jesień    2.7 26.51
4 samica wiosna    3.0 24.78
2 samica jesień    4.1 26.06
> skunks[order(skunks$PLEC),]
    PLEC  SEZON CIEZAR FLUOR
1 samica jesień    2.7 26.51
2 samica jesień    4.1 26.06
4 samica wiosna    3.0 24.78
5 samica jesień    4.5 25.97
3 samiec   zima    3.6 36.02

 

Funkcja order może mieć wiele argumentów. Najpierw sortuje dane względem pierwszej wskazanej zmiennej (najczęściej czynnika), potem w obrębie tych samych wartości pierwszej zmiennej sortuje dane względem drugiej zmiennej itd. Ostatecznie tworzy ciąg liczbowy odpowiadający pozycjom wierszy w pierwotnej bazie danych jakie mają wiersze po wykonanych sortowaniach. Można to wykorzystać by uzyskać bazę posortowana według dowolnie przyjętych kryteriów.

> skunks
    PLEC  SEZON CIEZAR FLUOR
1 samica jesień    2.7 26.51
2 samica jesień    4.1 26.06
3 samiec   zima    3.6 36.02
4 samica wiosna    3.0 24.78
5 samica jesień    4.5 25.97
> skunks[order(skunks$PLEC, skunks$SEZON, skunks$CIEZAR), ]
    PLEC  SEZON CIEZAR FLUOR
1 samica jesień    2.7 26.51
2 samica jesień    4.1 26.06
5 samica jesień    4.5 25.97
4 samica wiosna    3.0 24.78
3 samiec   zima    3.6 36.02

 

Najczęściej po sortowaniu zapamiętuje się wynik w postaci obiektu w R, często o takiej samej nazwie jak obiekt przed sortowaniem, np.: skunks=skunks[order(skunks$PLEC, skunks$SEZON, skunks$CIEZAR), ].

Funkcje i działania na bazach danych

Przy pracy nad bazami danych często należy sobie przypominać nazwy kolumn (czy zostały napisane dużymi, czy małymi literami, z kropkami czy podkreśleniami itp.). Gdy baza jest duża nazw tych możemy długo szukać poprzez jej wyświetlanie. Przy szukaniu tych nazw kolumn przydatnymi funkcjami są, names(), str() oraz summary().

> skunks
    PLEC  SEZON CIEZAR FLUOR
1 samica jesień    2.7 26.51
2 samica jesień    4.1 26.06
3 samiec   zima    3.6 36.02
4 samica wiosna    3.0 24.78
5 samica jesień    4.5 25.97
> names(skunks)
[1] "PLEC" "SEZON" "CIEZAR" "FLUOR"
> str(skunks)
'data.frame':   5 obs. of  4 variables:
$ PLEC  : Factor w/ 2 levels "samica","samiec": 1 1 2 1 1
$ SEZON : Factor w/ 3 levels "jesień","wiosna/lato",..: 1 1 3 2 1
$ CIEZAR: num 2.7 4.1 3.6 3 4
$ FLUOR     : num 26.51 26.06 36.02 24.78 25.97
> summary(skunks)
     PLEC      SEZON       CIEZAR         FLUOR
samica:4   jesień:3   Min.   :2.70   Min.   :24.78
samiec:1   wiosna:1   1st Qu.:3.00   1st Qu.:25.97
zima  :1   Median :3.60   Median :26.06
Mean   :3.58   Mean   :27.87
3rd Qu.:4.10   3rd Qu.:26.5.1
Max.   :4.50   Max.   :36.02

 

Dwie ostatnie funkcje pokazują zarówno nazwy zmiennych jak i nazwy wartości zmiennych czynnikowych, co może być bardzo przydatne.

Liczbę wierszy i kolumn bazy danych obliczymy za pomocą funkcji nrow(), ncol() i length() (dwie ostatnie funkcje wyznaczają liczbę kolumn).

> skunks
    PLEC  SEZON CIEZAR FLUOR
1 samica jesień    2.7 26.51
2 samica jesień    4.1 26.06
3 samiec   zima    3.6 36.02
4 samica wiosna    3.0 24.78
5 samica jesień    4.5 25.97
> nrow(skunks)
[1] 5
> ncol(skunks)
[1] 4
> length(skunks)
[1] 4

 

Generalnie bazy danych służą do opracowanej prezentacji wyników. Składają się na nie tabele z liczbami obiektów o różnych wartościach zmiennych dyskretnych, tabele z średnimi i odchyleniami standardowymi zmiennych ciągłych dla różnych wartości zmiennych dyskretnych, korelacje między różnymi wartościami zmiennych ciągłych i wykresy obrazujące te zależności. Czasem wykonuje się też wykresy rozkładów z próby zmiennych ciągłych (tzw. histogramy), co stanowi przybliżenie rozkładu, jaki tworzy zmienna dla wszystkich obiektów populacji i co tak naprawdę jest przedmiotem badań biologów. Na koniec sprawdza się, czy zaobserwowane zależności są istotne statystycznie, co oznacza sprawdzenie, czy zależności zaobserwowane dla prób przenoszą się na całe rozkłady.

opracowanie graficzne wyników i praktycznie wszystkie testy statystyczne. Trzeba się tylko nauczyć jak to zrobić, by były one wykonane poprawnie. Graficznemu opracowaniu danych poświęcona jest część III niniejszego podręcznika, a statystyce – część IV. W tym rozdziale podamy tylko podstawowe informacje jak zastosować funkcje matematyczne i statystyczne dla danych zapisanych w postaci data.frame. Można to poćwiczyć na całej bazie skunks, która można uzyskać po skopiowaniu do R następującego kodu:

skunks=data.frame(PLEC=c("samica", "samica", "samiec", "samica", 
 "samica", "samiec", "samiec", "samiec", "samiec", "samica", "samica",
 "samiec","samiec",  "samica", "samiec", "samiec", "samiec", "samica", 
 "samiec", "samica", "samiec",  "samiec", "samica", "samica", "samica",
 "samiec","samiec", "samica", "samica",  "samica", "samiec", "samica",
 "samiec", "samiec", "samiec", "samica", "samiec",  "samica", "samica",
 "samica", "samiec", "samiec", "samiec", "samica", "samiec",  "samiec",
 "samiec", "samica", "samiec", "samiec"),
SEZON=c("jesień", "jesień", "zima", "wiosna", "jesień", "zima", "wiosna",
 "zima",  "wiosna", "zima", "zima", "wiosna", "jesień", "jesień", "wiosna",
 "jesień", "wiosna", "zima", "jesień", "zima", "jesień", "zima", "zima",
 "wiosna", "zima", "zima", "wiosna", "wiosna", "zima", "zima", "zima",
 "jesień", "wiosna", "wiosna", "zima", "wiosna", "zima", "wiosna",
 "jesień", "zima", "wiosna", "jesień", "zima", "jesień", "wiosna",
 "jesień", "wiosna", "wiosna", "zima", "wiosna"),
CIEZAR=c(2.7, 4.1, 3.6, 3,4, 3.4, 2.6, 3.2, 3.6, 3.4, 4.2, 3.4, 4.8, 3.1, 3.7, 
3.5,  4.1, 3.3, 2.9, 3.1, 4.2, 4.1, 3, 3.5, 4.4, 3.9, 4.8, 4, 4.5, 4, 4.5, 3.9,
 3.6, 3.5,  3.5, 2.4, 4.2, 3.8, 3.3, 3.9, 3.3, 3.5, 3.8, 3.7, 4.4, 3.9, 3.8, 3, 
4.5, 4.4),
FLUOR=c(26.24, 24.69, 35.30, 25.45, 24.30, 38.59, 31.45, 37.14, 29.18, 33.32,
 29.06, 30.40, 36.28, 28.14, 29.18, 30.81, 28.70, 30.74, 35.08, 26.74, 30.31, 
 33.59, 28.61, 25.28, 27.29, 35.56, 28.63, 22.53, 31.49, 29.72, 36.43, 26.39, 
 29.12, 29.31, 36.54,  23.50, 34.36, 24.87, 27.83, 31.18, 28.96, 32.34, 38.56, 
 29.20, 31.31, 30.08, 31.96, 23.94, 37.59, 27.20))

 

Tabele z liczbą zbadanych osobników w dla każdej wartości zmiennych dyskretnych uzyskuje się za pomocą funkcji table(). Jest to funkcja działająca na argumentach różnego typu dająca wyniki, których najczęściej się oczekuje (choć nie zawsze).

> table(skunks$PLEC)


samica samiec
22     28 
> table(skunks$PLEC,skunks$SEZON)


jesień wiosna zima
samica      7      6    9
samiec      6     12   10
> table(skunks$PLEC, skunks$SEZON, skunks$CIEZAR>3.5)
, ,  = FALSE


jesień wiosna zima
samica      3      4    4
samiec      3      4    3

, ,  = TRUE


jesień wiosna zima
samica      4      2    5
samiec      3      8    7

 

Sposób wyświetlania się wyników zależy od kolejności wpisywanych zmiennych. Trzeba tym manipulować, by uzyskać taki wynik, jaki pasuje do zaplanowanej w opracowaniu tabeli. Po uzyskaniu odpowiedniej tabeli należy jej kod przypisać jakiemuś obiektowi. Trzeba w konsoli wykonać instrukcję postaci:

tab1 = table(skunks$PLEC,skunks$SEZON)W przypadku, gdy porządek alfabetyczny dla zmiennych nieliczbowych jest sprzeczny z naturalnym porządkiem określonym np. przez następstwo czasowe lub przestrzenne, można nadać im własny porządek pamiętany później do końca sesji. Wykonuje się to funkcją ordered() opisaną już w rozdziale o czynnikach.

> table(skunks$PLEC,skunks$SEZON)


jesień wiosna zima
samica      7      6    9
samiec      6     12   10
> skunks$SEZON=ordered(skunks$SEZON, levels=c("wiosna", "jesień", "zima"))
> table(skunks$PLEC,skunks$SEZON)


wiosna jesień zima
samica      6      7    9
samiec     12      6   10

 

Funkcją, która błyskawicznie umożliwia wyliczenie średnich i odchyleń standardowych (a także innych charakterystyk rozkładu) w R jest aggregate() o składni:

aggregate(zmienna_ciągła ~ zmienna_dyskretna, nazwabazy, “nazwa funkcji”)

Nazwa funkcji to najczęściej sum, mean, sd i inne funkcje przetwarzające wektory. Można je zapisać za pomocą nazw, albo w postaci: function(x) sum(x),function(x) mean(x), function(x) sd(x) lub jakakolwiek inna funkcja. Ta postać pozwala na używanie niestandardowych funkcji i wyliczenie kilku charakterystyk jednocześnie. Zwracamy w nich uwagę na to, z jaką dokładnością ukazują się wyliczane średnie i odchylenia standardowe, gdyż musi być to taka sama dokładność, z jaką dokonywane były pomiary.

> skunks$SEZON=ordered(skunks$SEZON, levels=c("wiosna/lato", "jesień", "zima"))
> aggregate(CIEZAR ~ SEZON+PLEC, skunks, mean)
   SEZON   PLEC   CIEZAR
1 wiosna samica 3.283333
2 jesień samica 3.542857
3 zima samica 3.755556
4 wiosna samiec 3.766667
5 jesień samiec 3.800000
6 zima samiec 3.870000
> aggregate(CIEZAR ~ SEZON+PLEC, skunks, function(x) c(mean(x),sd(x)))
   SEZON   PLEC  CIEZAR.1  CIEZAR.2
1 wiosna samica 3.2833333 0.5946988
2 jesień samica 3.5428571 0.5223573
3   zima samica 3.7555556 0.5681354
4 wiosna samiec 3.7666667 0.5898125
5 jesień samiec 3.8000000 0.6572671
6   zima samiec 3.8700000 0.4522782
> aggregate(CIEZAR ~ SEZON+PLEC, skunks,
+ function(x) paste(mean(x),"+",sd(x)))
   SEZON   PLEC                               CIEZAR
1 wiosna samica 3.28333333333333 + 0.594698803316996
2 jesień samica  3.54285714285714 + 0.52235729425092
3   zima samica  3.75555555555556 + 0.56813535163531
4 wiosna samiec 3.76666666666667 + 0.589812502307969
5 jesień samiec              3.8 + 0.657267069006199
6   zima samiec              3.87 + 0.45227818381562
> aggregate(CIEZAR ~ SEZON+PLEC, skunks,
+ function(x) paste(round(mean(x),1),"+",round(sd(x),1)))
   SEZON   PLEC    CIEZAR
1 wiosna samica 3.3 + 0.6
2 jesień samica 3.5 + 0.5
3   zima samica 3.8 + 0.6
4 wiosna samiec 3.8 + 0.6
5 jesień samiec 3.8 + 0.7
6   zima samiec 3.9 + 0.5

 

Najbardziej jednak chcielibyśmy utworzyć tabelę postaci:

Można zrobić tylko tekstową namiastkę takiej tabeli bez linii pionowych i poziomych posługując się znanymi już typami obiektów i funkcjami.

> skunks$SEZON=ordered(skunks$SEZON, levels=c("wiosna", "jesień", "zima"))
> agg=aggregate(CIEZAR ~ SEZON+PLEC, skunks,
+ function(x) paste(round(mean(x),1),intToUtf8(177),round(sd(x),1)))
> wyn=agg[,3]
> mac=matrix(wyn,3,2,dimnames=list(c("wiosna","jesień","zima"),c("samice","samce")))
> mac
       samice      samce
wiosna "3.3 ± 0.6" "3.8 ± 0.6"
jesień "3.5 ± 0.5" "3.8 ± 0.7"
zima   "3.8 ± 0.6" "3.9 ± 0.5"
> print(mac,quote=FALSE)
       samice    samce
wiosna 3.3 ± 0.6 3.8 ± 0.6
jesień 3.5 ± 0.5 3.8 ± 0.7
zima   3.8 ± 0.6 3.9 ± 0.5

 

Tabele spełniającą wyznaczone kryteria należy zapamiętać jako obiekt R, czyli wykonać instrukcje:

Tab2 = aggregate(CIEZAR ~ SEZON+PLEC, skunks, ....... )
Tab3 = aggregate(FLUOR ~ SEZON+PLEC, skunks, ....... )

albo

wyn2 = aggregate(CIEZAR ~ SEZON+PLEC, skunks, ....... )[3,]
Tab2 = matrix(wyn2,3,2,dimnames=list(
c("wiosna","jesień","zima"),c("samice","samce")))
wyn3 = aggregate(FLUOR ~ SEZON+PLEC, skunks, ....... )[3,]
Tab3 = matrix(wyn3,3,2,dimnames=list(
c("wiosna","jesień","zima"),c("samice","samce")))

Najpierw, oczywiście należy powyższe instrukcje dokończyć. Po uzyskaniu stosownych obiektów w R, należy je zapamiętać w postaci własnego skrótu do R wykonując instrukcję

save.image("Własna Nazwa.RData")

.

W pokazanych procedurach chodzi o wyświetlenie wyników w takiej postaci tekstowej, by po przeniesieniu ich do edytora tekstów (gdzie opisuje się wyniki) wymagały one minimalnej przeróbki. W konsoli R nie można tworzyć takich tabel, jakie znamy z publikowanych opracowań. Tabele do publikacji tworzy się w edytorach tekstu i dane uzyskane w R kopiuje się do edytora, w którym poddaje się je standardowej obróbce. Przy takim planie pracy najlepiej zrezygnować z używania znaku ± w R, i zamienić + dopiero edytorze tekstu.

Eksportowanie tabel

Wyniki wielu obliczeń są obiektami typu data.frame() lub matrix(). Ich obraz wyświetlany w konsoli i przeniesiony do edytora tekstu nie tworzy tabeli. Aby nie męczyć się z tworzeniem tabeli i wstawianiem w odpowiednie komórki wyników należy:

  1. eksportować tabelę do pliku tekstowego,
  2. otworzyć plik tekstowy w arkuszu kalkulacyjnym w postaci tabeli,
  3. skopiować tabelę do edytora tekstu,

Eksport do pliku tekstowego tabeli lub macierzy wykonuje się za pomocą funkcji write.table().

Przykładem bazy danych mogą być badania stężenia fluoru w wydzielinie gruczołów odbytowych skunksów. Można wykonać trzy tabele, które będą potrzebne do wykonania projektu pracy dyplomowej:

> skunks$SEZON=ordered(skunks$SEZON, levels=c("wiosna", "jesień", "zima"))
> tab_policz=table(skunks$PLEC,skunks$SEZON)
> tab_ciezar=aggregate(CIEZAR~PLEC+SEZON,skunks,
+   function(x) paste(round(mean(x),1),"+",round(sd(x),1)))
> tab_fluor=aggregate(FLUOR~PLEC+SEZON,skunks,
+   function(x) paste(round(mean(x),2),"+",round(sd(x),2)))
> write.table(tab_policz,"tab1.txt",sep="\t")
> write.table(tab_ciezar,"tab2.txt",sep="\t")
> write.table(tab_fluor,"tab3.txt",sep="\t")

 

Efektem wykonania tego programu są następujące pliki tekstowe:

Pliki te można wczytać do Excela metodą:

Otworzyć jakikolwiek plik Excela (może być nowy)

  • W Excelu kliknąć na otwórz
  • Określić folder na ten, gdzie zapisane zostały pliki tab1.txt, tab2.txt, tab3.txt
  • Zmienić opcję “wszystkie pliki programu excel” na “Pliki tekstowe .prn, .txt, .csv”
  • Powinny się pokazać pliki tab1.txt, tab2.txt i tab3.txt.
  • Kliknąć na importowany plik i “Otwórz”
  • Pozostawić “Rozdzielony”, kliknąć na “Dalej”
  • Pozostawić odhaczony tabulator, lub go odhaczyć i kliknąć “Dalej”
  • Kliknąć “Zakończ”

Jedynymi poprawkami, jakie trzeba będzie wykonać – to przesunąć nazwy kolumn o jedno pole w prawo. Zamianę kropek w liczbach na przecinki także jest lepiej wykonać w Excelu, gdyż można wtedy zaznaczyć wyłącznie pola liczbowe i nie dokonywać tych zmian w nazwach wierszy.

W arkuszu kalkulacyjnym libre Office należy wybrać otwórz, zmienić katalog na właściwy i wybrać odpowiedni plik tekstowy. W polu które się pojawi, musi być odhaczony tabulator. Na ogół od razu importowana tabela wygląda dobrze. Należy tylko przesunąć nazw kolumn w prawo o jedno pole, co robi się już po zaimportowaniu tabeli do arkusza kalkulacyjnego. Również zamianę kropek na przecinki w liczbach najlepiej wykonać na końcu zaznaczając wyłącznie pola liczbowe.

Często tabele zaimportowane do arkusza kalkulacyjnego przetwarza się na prostsze formy mające charakter tabeli krzyżowej. Często też łączy się ze sobą komórki z tą sama wartością tekstową, gdy występują obok siebie lub jedna pod drugą. Tabele przenoszone z arkusza kalkulacyjnego do edytora tekstu zachowują format tabeli. Dopiero w edytorze tekstu zamienia się znak “+” na “±”, gdyż podczas eksportowania, importowania lub przenoszenia tabeli metodą kopiuj-wklej znaki “±” może zostać zamieniony na inny znak często nie występujący na klawiaturze i czasem taki, który trudno automatycznie zmienić na “±”.

Tags:
Spis treści