Rozdział 4 Ramki danych i macierze
W poprzednim rozdziale omówiono kilka schematów posługiwania się wektorami, który są jednocześnie najbardziej elementarnym sposobem przetwarzania danych w R.
4.1 Ramki danych
Przy analizie danych (w tym także danych meteorologicznych) wykorzystywane są inne niż wektory schematy przechowywania i przetwarzania danych. Najczęściej są to tzw. ramki danych (ang. data frame), które na pierwszy rzut oka przypominają tradycyjną “tabelkę z Excela”.
Najważniejsze cechy ramki danych wypisano poniżej:
- Każda ramka danych powinna zawierać wartości uporządkowane w kolumnach.
- Każda z kolumn jest wektorem i musi mieć taką samą długość.
- Różne kolumny mogą przechowywać różne typy danych.
Poniżej zamieszczono fragment ramki danych zawiera dane pomiarowe ze stacji Wojewódzkiego Inspektoratu Ochrony Środowiska - Poznań-Polanka. W kolumnie date zawarto dane w typie umożliwiającym przechowywanie czasu, w kolejnych kolumnach umieszczono wartości koncentracji PM10, PM2.5, temperatury powietrza, prędkości wiatru o oraz kierunku wiatru.
## date PZ_Pol_pm10 PZ_Pol_pm25 PZ_T2M PZ_WS PZ_WD
## 95034 2016-11-07 17:00:00 24 16 4 1 278
## 95035 2016-11-07 18:00:00 22 17 4 1 287
## 95036 2016-11-07 19:00:00 22 17 3 1 322
## 95037 2016-11-07 20:00:00 23 16 3 1 326
## 95038 2016-11-07 21:00:00 24 16 3 0 307
## 95039 2016-11-07 22:00:00 24 16 2 0 303
4.2 Praca na ramkach danych
Do nauki pracy na ramkach danych wykorzystamy domyślnie wgrane zbiór danych o nazwie airquality. Wczytanie przykładowego zbioru danych wgranego wraz z R jest możliwe poprzez funkcję data()
. Nasz zbiór nazywa się airquality
. Szczegóły dotyczące analizowanego zbioru danych dostępne są po wydaniu komendy ?airquality
lub ?"airquality"
Jeśli chcemy wczytać i wyświetlić pierwsze kilka rzędów naszej ramki danych spróbujmy najpierw ją wczytać do pamięci komputera a następnie wyświetlić pierwsze lub ostatnie 6 wierszy za pomocą funkcji head()
lub tail()
data("airquality")
head(airquality) # funkcja head() wyświetla pierwsze 6 wartości
## Ozone Solar.R Wind Temp Month Day
## 1 41 190 7.4 67 5 1
## 2 36 118 8.0 72 5 2
## 3 12 149 12.6 74 5 3
## 4 18 313 11.5 62 5 4
## 5 NA NA 14.3 56 5 5
## 6 28 NA 14.9 66 5 6
Po wczytaniu ramki danych powinna być ona dostępne w prawym górnym rogu środowiska RStudio w zakładce Environment. Możesz kliknąć w tabelkę widoczną obok nazwy ramki danych i wyświetlić jej zawartość w postaci graficznej. Klikając na nazwę kolumny możesz także automatycznie posortować bieżący widok rosnąco/malejąco względem wartości w danej kolumnie. Standardowo, po wczytaniu zbioru danych można użyć funkcję summary()
wyświetlającą podsumowanie statystyczne wartości w poszczególnych kolumnach ramki danych.
4.2.1 Jak odnosić się do elementów ramki?
4.2.1.1 Odniesienie przez nazwę
Wyboru kolumny z ramki danych dokonuje się za pomocą operatora $
poprzedzonego nazwą ramki danych a po znaku $
wpisuje się nazwę kolumny. Jeśli nie jesteśmy pewni jakie są nazwy kolumn w naszej ramce danych można je zawsze sprawdzić za pomocą funkcji colnames()
lub names()
. Pamiętaj także o stosowaniu tabulatora!
Przykładowo, jeśli chcemy pobrać do analizy całą kolumnę z wartościami temperatur (Temp) z ramki danych airquality
to komenda powinna wyglądać następująco:
airquality$Temp
## [1] 67 72 74 62 56 66 65 59 61 69 74 69 66 68 58 64 66 57 68 62 59 73 61
## [24] 61 57 58 57 67 81 79 76 78 74 67 84 85 79 82 87 90 87 93 92 82 80 79
## [47] 77 72 65 73 76 77 76 76 76 75 78 73 80 77 83 84 85 81 84 83 83 88 92
## [70] 92 89 82 73 81 91 80 81 82 84 87 85 74 81 82 86 85 82 86 88 86 83 81
## [93] 81 81 82 86 85 87 89 90 90 92 86 86 82 80 79 77 79 76 78 78 77 72 75
## [116] 79 81 86 88 97 94 96 94 91 92 93 93 87 84 80 78 75 73 81 76 77 71 71
## [139] 78 67 76 68 82 64 71 81 69 63 70 77 75 76 68
Zadania kontrolne
Wiedząc, że wynikiem pobrania kolumny z ramki danych jest wektor oblicz średnią temperaturę powietrza zbioru
airquality
w Fahrenheitach oraz stopniach Celsjusza(T[*C] = (T[*F]-32)*(5/9))
Oblicz minimalną prędkość wiatru z pierwszych 20-tu pomiarów
Utwórz histogram temperatur (funkcja
hist()
)
4.2.1.2 Odniesienie przez indeks
Praca na wartościach przechowywanych w ramkach danych możliwa jest także poprzez indeksowanie operatorem []
, którego używaliśmy poprzednio przy wektorach. Jedyna różnica polega na tym, że w nawiasie kwadratowym należy zadeklarować 2 wektory określejące położenie wierszy i kolumn oddzielone przecinkiem.
Przed przecinkiem należy wskazać indeksy wierszy, a po przecinku indeksy kolumn. Jeżeli pole indeksujące wierszy lub kolumn pozostanie puste wówczas zostają wybrane wszystkie elementy.
Jeśli chcemy wybrać wszystkie wartości z kolumny Temp
wówczas musimy wiedzieć, że jest to 4-ta kolumna. Jako, że chcemy wybrać wszystkie rzędy to równoważnik dla komendy airquality$Temp
to: airquality[,4]
.
Jeśli chcemy wyświetlić cały pierwszy rząd to polecenie powinno wyglądać następująco:
airquality[1,]
## Ozone Solar.R Wind Temp Month Day
## 1 41 190 7.4 67 5 1
Można także wskazać dowolne wiersze, np. od 10-ego do 15-ego w odwrotnej kolejności i tylko wybrane kolumny, np. dla ozonu i wiatru (1-sza i 3-cia). Istotne jest tylko podanie odpowiedniego wektora wartości w odpowiednich miejscach:
airquality[15:10,c(1,3)]
## Ozone Wind
## 15 18 13.2
## 14 14 10.9
## 13 11 9.2
## 12 16 9.7
## 11 7 6.9
## 10 NA 8.6
Zadania kontrolne
Ze zbioru
airquality
wybierz za pomocą jednego polecenia wiersze: 5-10, 15-17 i 100-102 oraz wszystkie kolumnyKorzystając z indeksów ujemnych (tzw. wybór przez negację pomiń pierwsze 3 kolumny i pierwsze 100 wierszy)
Korzystając z wyrażeń logicznych lub funkcji
which()
wyświetl jedynie wiersze, w których temperatura powietrza była wyższa niż 90*F
4.2.2 Tworzenie ramek danych
Tworzenie i modyfikacje ramek danych jest możliwe przynajmniej na kilka sposobów. Najbardziej podstawowym jest zastosowanie funkcji data.frame()
, która jako argumenty przyjmuje wartości wektorów o równych długościach. Przykładowy fragment kodu stworzy nam ramkę danych nazwaną ramka
zawierającą 3 nazwane kolumny i 5 wierszy:
ramka <- data.frame(literki=letters[1:5], cyferki=1:5, losowe=runif(5))
ramka
## literki cyferki losowe
## 1 a 1 0.3140620
## 2 b 2 0.8211992
## 3 c 3 0.7793354
## 4 d 4 0.1656139
## 5 e 5 0.8295460
4.2.2.1 Modyfikacja ramek danych
Dane przechowywane w ramkach danych można modyfikować. Jeśli zmiana ma dotyczyć pojedynczej wartości to należy stworzyć komendę zwracającą nam tą wartość i nadpisać do niej nową wartość operatorem przypisania. Przykładowo, modyfikacja pierwszej wartości temperatury powietrza ze zbioru airquality
możliwa jest w poniższy sposób:
airquality$Temp[1] # wyswietlamy wartosc pierwotna
## [1] 67
airquality$Temp[1] <- 100 # nadajemy nowa wartosc
head(airquality) # wyswietlamy dla pewnosci pierwsze 6 rzedow
## Ozone Solar.R Wind Temp Month Day
## 1 41 190 7.4 100 5 1
## 2 36 118 8.0 72 5 2
## 3 12 149 12.6 74 5 3
## 4 18 313 11.5 62 5 4
## 5 NA NA 14.3 56 5 5
## 6 28 NA 14.9 66 5 6
Często do istniejącej ramki danych chcemy dopisać wyniki obliczeń jako nową kolumnę. W R łączenie odpowiednich obiektów w ramki danych po kolumnach jest możliwe dzięki funkcji cbind.data.frame()
, natomiast do łączenia po wierszach służy funkcja rbind.data.frame()
.
Do utworzenia nowej kolumny szybszym rozwiązaniem w wielu przypadkach jest po prostu wykorzystanie do tego celu operatora przypisania <-
wraz z odwołaniem do istniejącej ramki danych i nazwą nowej kolumny. Przeliczmy zatem temperaturę z Fahrenheitów na stopnie Celsjusza i zapiszmy je w kolumnie TempC
:
# przeliczamy temperature z Fahrenheitow na Celsjusze i zapisujemy do nowej
# kolumny 'TempC'
airquality$TempC <- (airquality$Temp-32)*(5/9)
head(airquality) # wyswietlmy pierwsze 6 rzedow dla pewnosci
## Ozone Solar.R Wind Temp Month Day TempC
## 1 41 190 7.4 100 5 1 37.77778
## 2 36 118 8.0 72 5 2 22.22222
## 3 12 149 12.6 74 5 3 23.33333
## 4 18 313 11.5 62 5 4 16.66667
## 5 NA NA 14.3 56 5 5 13.33333
## 6 28 NA 14.9 66 5 6 18.88889
4.3 Macierze
Oprócz ramek danych bardzo często w zastosowaniach GIS lub na potrzeby tzw. reanaliz meteorologicznych stosowane są dane zapisane w formie wielowymiarowych macierzy. Macierze w najprostszej postaci (2-wymiarowej) to po prostu tabele z danymi, wizualnie bardzo podobne do ramek danych, przy czym nie posiadają one nazw kolumn i nie można się do nich odnosić poprzez nazwę a jedynie poprzez []
.
Tworzenie macierzy wielowymiarowych odbywa się poprzez funkcję array()
a w postaci 2-wymiarowej prostsza w użyciu jest funkcja matrix()
(w dosłownym tłumaczeniu macierz). Za pomocą opcji nrow
oraz ncol
można zadeklarować liczbę wierszy i kolumn tworzonej macierzy. Przykładowo:
matrix(1:12, nrow=3) # tworzymy macierz z wartościami od 1 do 12 w 3-ech rzedach
## [,1] [,2] [,3] [,4]
## [1,] 1 4 7 10
## [2,] 2 5 8 11
## [3,] 3 6 9 12
matrix(1:12, ncol=3) # tworzymy macierz z wartościami od 1 do 12 w 3-ech kolumnach
## [,1] [,2] [,3]
## [1,] 1 5 9
## [2,] 2 6 10
## [3,] 3 7 11
## [4,] 4 8 12
Zwróć uwagę, że poszczególne elementy są użyte do wypełnienia w pierwszej kolejności 1-szej kolumny, potem 2-giej, itd. Jeśli chcemy użyć danych do wypełnienia po rzędach, musimy komputer o tym poinformować za pomocą opcji byrow=T
:
m2<-matrix(1:12,ncol=3,byrow=T)
m2
## [,1] [,2] [,3]
## [1,] 1 2 3
## [2,] 4 5 6
## [3,] 7 8 9
## [4,] 10 11 12
Tworzenie macierzy można wykonywać np. poprzez złączenie kolumn lub rzędów o jednakowej długości. W zależności od tego w jaki sposób chcemy macierz utworzyć wykorzystujemy funkcje cbind()
, (skrót od column bind) lub rbind()
(skrót od row bind):
x <- c(1,3,2,10,5) # tworzymy wektor 'x'
x
## [1] 1 3 2 10 5
y <- 1:5 # tworzymy wektor 'y'
m1<-cbind(x,y) # laczymy wektory po kolumnach i tworzymy macierz 'm1'
m1 # wyswietlamy powstala macierz
## x y
## [1,] 1 1
## [2,] 3 2
## [3,] 2 3
## [4,] 10 4
## [5,] 5 5
Analogicznie można utworzyć macierz łącząc wektory po wierszach za pomocą funkcji rbind()
:
m2 <- rbind(x,y) # laczymy po wierszach i tworzymy nowa macierz `m2`
m2
## [,1] [,2] [,3] [,4] [,5]
## x 1 3 2 10 5
## y 1 2 3 4 5
Możemy także uzyskać podstawowe informacje oraz wykonać podstawowe operacje matematyczne na macierzach:
dim(m1) # podaje wymiary macierzy
## [1] 5 2
t(m1) # transpozycja
## [,1] [,2] [,3] [,4] [,5]
## x 1 3 2 10 5
## y 1 2 3 4 5
5.2*m1 # iloczyn skalarny
## x y
## [1,] 5.2 5.2
## [2,] 15.6 10.4
## [3,] 10.4 15.6
## [4,] 52.0 20.8
## [5,] 26.0 26.0
m1+m1 # dodawanie macierzy
## x y
## [1,] 2 2
## [2,] 6 4
## [3,] 4 6
## [4,] 20 8
## [5,] 10 10
m1*m1 # mnożenie analogicznych elementów
## x y
## [1,] 1 1
## [2,] 9 4
## [3,] 4 9
## [4,] 100 16
## [5,] 25 25
4.3.1 Indeksowanie macierzy
Wyciąganie poszczególnych elementów z macierzy wymaga zadeklarowania jej wszystkich wymiarów:
m2<-matrix(c(1,3,2,5,-1,2,2,3,9),ncol=3,byrow=T);m2
## [,1] [,2] [,3]
## [1,] 1 3 2
## [2,] 5 -1 2
## [3,] 2 3 9
# tworzymy macierz i ją wyświetlamy
m2[2,3] #element macierzy m2 w 2-gim rzędzie i 3-ciej kolumnie
## [1] 2
m2[2,] #cały 2-gi rząd
## [1] 5 -1 2
m2[,3] #cała 3-cia kolumna
## [1] 2 2 9
m2[-1,] #cała macierz m2 bez pierwszego rzędu
## [,1] [,2] [,3]
## [1,] 5 -1 2
## [2,] 2 3 9
m2[,-1] #i bez pierwszej kolumny
## [,1] [,2]
## [1,] 3 2
## [2,] -1 2
## [3,] 3 9
…
Macierze w naukach atmosferycznych są stosowane przede wszystkim do nieco bardziej skomplikowanych obliczeń oraz do wizualizacji danych. Przetestujmy to drugie zastosowanie wczytując zbiór danych volcano
zawierający cyfrowy model terenu pewnego wulkanu i zwizualizujmy go za pomocą funkcji image()
oraz contour()
lub jako model 3d z użyciem funkcji persp()
. Postaraj się uzyskać poniższy efekt:
Zadanie domowe
- Wykonaj przykłady z podręcznika P. Biecka dotyczące ramek danych i macierzy
- Przeczytaj z ww. podręcznika rozdział dotyczący list i ogólnego schematu pracy na danych tego typu