Macierze wielowymiarowe – tablice
Tworzenie macierzy wielowymiarowej
Macierze są obiektami dwuwymiarowymi. Tymczasem w biologii często zachodzi potrzeba operowania podobnymi obiektami o wielu wymiarach. Potrzeba ich stosowania pojawia się głównie w programowaniu, gdy dane potrzebne do działań zależą od wartości k czynników. Numerując wartości i-tego czynnika liczbami 1,2,…,ni można odpowiednią wartość zapisać pod kryptonimem wart[j1,j2,…,jk]. Przykładowo, średnie ciężary osobników obu płci, pięciu gatunków w trzech lokalizacjach, można zapisać w 3-wymiarowej macierzy o rozmiarach 2×5×3, gdzie macierz[1,1,1] oznacza średni ciężar samic pierwszego gatunku w 1 lokalizacji, macierz[2,4,3] średni ciężar samców trzeciego gatunku w trzeciej lokalizacji itd. Nie jest to wygodne do obrazowania danych, ale przy przetwarzaniu danych względem wielu czynników może być bardzo przydatne. Tego typu macierze wielowymiarowe tworzy się funkcją array() z obowiązkową opcją dim=c(n1,n2,…,nk), gdzie k jest liczbą wymiarów, a ni liczbą różnych wartości i-tego czynnika (rozmiarem i-tego wymiaru).
> tab=array(1:24,dim=c(4,3,2)) > tab , , 1 [,1] [,2] [,3] [1,] 1 5 9 [2,] 2 6 10 [3,] 3 7 11 [4,] 4 8 12 , , 2 [,1] [,2] [,3] [1,] 13 17 21 [2,] 14 18 22 [3,] 15 19 23 [4,] 16 20 24 |
Gdy liczba elementów ciągu, z którego tworzy się tablicę o rozmiarach c(n1, n2, …,nk), jest mniejsza od n1n2…nk ciąg ten jest kilkakrotnie powtarzany.
> tab=array(1:7,dim=c(4,3,2)) > tab , , 1 [,1] [,2] [,3] [1,] 1 5 2 [2,] 2 6 3 [3,] 3 7 4 [4,] 4 1 5 , , 2 [,1] [,2] [,3] [1,] 6 3 7 [2,] 7 4 1 [3,] 1 5 2 [4,] 2 6 3 |
Funkcja table() tworzy szczególną macierz wielowymiarową, tzw. tablicę. Argumentami tej funkcji są jeden, dwa lub więcej wektorów równej długości. Wynikiem jest liczba układów (wek1[i],wek2[i],wek3[i],…), które się w tych wektorach powtarzają.
> wek1=c("a","a","b","b","c","d") > wek2=c(1,2,3,3,2,1) > wek3=c("duże", "duże", "małe", "duże", "małe", "małe") > table(wek1) wek1 a b c d 2 2 1 1 > table(wek2, wek2) wek2 wek1 1 2 3 a 1 1 0 b 0 0 2 > table(wek2, wek2, wek3) , , wek3 = duże wek2 wek1 1 2 3 a 1 1 0 b 0 0 1 c 0 0 0 d 0 0 0 , , wek3 = małe wek2 wek1 1 2 3 a 0 0 0 b 0 0 1 c 0 1 0 d 1 0 0 |
Zastosowanie funkcji class() do obiektu utworzonego funkcją array() pokazuje typ “array”, natomiast do tablicy utworzonej funkcją table() pokazuje typ “table”. Typy te różnią się drobnymi zmianami w sposobie nazywania poszczególnych wymiarów i wartości leżących na poszczególnych osiach. Pod innymi względami są identyczne. W dalszym ciągu pojęcia macierze wielowymiarowe jak i tablice będą używane wymiennie.
Nazywanie poszczególnych elementów macierzy wielowymiarowej
Wymiar zarówno macierzy jak i tablic może być dowolny, równy także 1 (wektor), jak i 2 (macierz). Wymiary są ciągami złożonymi z tylu elementów, ile podano na odpowiednim miejscu w opcji dim. Opcja “dimnames” pozwala na nazywanie elementów poszczególnych wymiarów. Jej wartością jest lista ciągów nazw. Nazwy te nie są i nie stają się obiektami R.
> ciezary=c(22.84, 15.44, 19.47, 17.85, 18.84, 14.38, 22.26, 15.50, 18.19, 16.73, 19.26, 11.41, 21.00, 14.69, 12.19, 20.11, 12.62, 16.45, 19.57, 20.22, 18.45, 14.43, 17.35, 14.51) > tab=array(ciezary,dim=c(4,3,2),dimnames=list(lokalizacja=c("Park","Zagajnik","Las","Puszcza"),gatunek=c("Aa", "Af", "Mg"),plec=c("samiec", "samica"))) > tab , , plec = samiec gatunek lokalizacja Aa Af Mg Park 22.84 18.84 18.19 Zagajnik 15.44 14.38 16.73 Las 19.47 22.26 19.26 Puszcza 17.85 15.50 11.41 , , plec = samica gatunek lokalizacja Aa Af Mg Park 21.00 12.62 18.45 Zagajnik 14.69 16.45 14.43 Las 12.19 19.57 17.35 Puszcza 20.11 20.22 14.51 |
Macierze wielowymiarowe zaimplementowane do R
Do R zaimplementowano interesującą tablicę czterowymiarową o nazwie Titanic, w które pokazano liczby pasażerów, którzy przeżyli i nie przeżyli katastrofy z podziałem na dzieci i dorosłych, kobiety i mężczyźni oraz status majątkowy pasażerów (pasażerowie pierwszej, drugiej i trzeciej klasy oraz załoga).
> Titanic , , Age = Child, Survived = No Sex Class Male Female 1st 0 0 2nd 0 0 3rd 35 17 Crew 0 0 , , Age = Adult, Survived = No Sex Class Male Female 1st 118 4 2nd 154 13 3rd 387 89 Crew 670 3 , , Age = Child, Survived = Yes Sex Class Male Female 1st 5 1 2nd 11 13 3rd 13 14 Crew 0 0 , , Age = Adult, Survived = Yes Sex Class Male Female 1st 57 140 2nd 14 80 3rd 75 76 Crew 192 20 |
Inna macierz trzywymiarowa o nazwie HairEyeColor, wykonana została dla potrzeb nauki różnych technik R i pokazuje liczby studentów statystki w 1974 roku na Uniwersytecie w Delavare z podziałem na płeć, kolor oczu i kolor włosów.
> HairEyeColor , , Sex = Male Eye Hair Brown Blue Hazel Green Black 32 11 10 3 Brown 53 50 25 15 Red 10 10 7 7 Blond 3 30 5 8 , , Sex = Female Eye Hair Brown Blue Hazel Green Black 36 9 5 2 Brown 66 34 29 14 Red 16 7 7 7 Blond 4 64 5 8 |
Odwoływanie się do elementów macierzy wielowymiarowej
Do poszczególnych komórek macierzy k-wymiarowej odwołujemy się zgodnie ze schematem: Macierz[i1,i2,…,ik] gdzie ij jest j-ta wartości i-tego czynnika. Możliwe są odwołania do wszystkich wartości i-tego czynnika poprzez zastosowanie pustych wartości na pozostałych miejscach jak i inne kombinacje liczb i pustych miejsc.
> tab=array(1:24,dim=c(4,3,2)) > tab , , 1 [,1] [,2] [,3] [1,] 1 5 9 [2,] 2 6 10 [3,] 3 7 11 [4,] 4 8 12 , , 2 [,1] [,2] [,3] [1,] 13 17 21 [2,] 14 18 22 [3,] 15 19 23 [4,] 16 20 24 > tab[1,,] [,1] [,2] [1,] 1 13 [2,] 5 17 [3,] 9 21 > tab[,1,] [,1] [,2] [1,] 1 13 [2,] 2 14 [3,] 3 15 [4,] 4 16 > tab[,,1] [,1] [,2] [,3] [1,] 1 5 9 [2,] 2 6 10 [3,] 3 7 11 [4,] 4 8 12 > tab[1,1,] [1] 1 13 |
W macierzach wielowymiarowych z nazwanymi elementami na osiach, odwoływać się można wymieniając nazwy poszczególnych elementów.
> tab=array(24:1,dim=c(4,3,2),dimnames=list(letters[1:4],letters[5:7],letters[8:9])) > tab , , h e f g a 24 20 16 b 23 19 15 c 22 18 14 d 21 17 13 , , i e f g a 12 8 4 b 11 7 3 c 10 6 2 d 9 5 1 > tab["b","e","h"] [1] 23 > tab["b",,] h i e 23 11 f 19 7 g 15 3 |
Edycja macierzy wielowymiarowych
Poszczególne wyrazy tablicy wielowymiarowej można zmieniać odwołując się do nich i wprowadzając nowe wartości. Zamieniać można pojedyncze wartości, wiersze i kolumny w poszczególnych przekrojach jak i części tablicy o większej liczbie wymiarów.
> tab=array(1:24,dim=c(4,3,2)) > tab , , 1 [,1] [,2] [,3] [1,] 1 5 9 [2,] 2 6 10 [3,] 3 7 11 [4,] 4 8 12 , , 2 [,1] [,2] [,3] [1,] 13 17 21 [2,] 14 18 22 [3,] 15 19 23 [4,] 16 20 24 > tab[1,,]=-tab[1,,] > tab , , 1 [,1] [,2] [,3] [1,] -1 -5 -9 [2,] 2 6 10 [3,] 3 7 11 [4,] 4 8 12 , , 2 [,1] [,2] [,3] [1,] -13 -17 -21 [2,] 14 18 22 [3,] 15 19 23 [4,] 16 20 24 |
Usuwanie zbędnych kolumn, wierszy w przypadku tablicy wielowymiarowych sprowadza się do usunięcia danych dla pewnych wartości czynników stanowiących wymiary tablicy. Można przy tym wymieniać, które wartości mają zostać lub te, które mają być usunięte.
> tab=array(1:24,dim=c(4,3,2)) > tab , , 1 [,1] [,2] [,3] [1,] 1 5 9 [2,] 2 6 10 [3,] 3 7 11 [4,] 4 8 12 , , 2 [,1] [,2] [,3] [1,] 13 17 21 [2,] 14 18 22 [3,] 15 19 23 [4,] 16 20 24 > tab1=tab[c(1,3),,] > tab1 , , 1 [,1] [,2] [,3] [1,] 1 5 9 [2,] 3 7 11 , , 2 [,1] [,2] [,3] [1,] 13 17 21 [2,] 15 19 23 # > tab2=tab[-c(2,4),,] > tab2 , , 1 [,1] [,2] [,3] [1,] 1 5 9 [2,] 3 7 11 , , 2 [,1] [,2] [,3] [1,] 13 17 21 [2,] 15 19 23 |
Nazwy poszczególnych wymiarów mogą być wprowadzone, zmienione lub usunięte poprzez funkcje dimnames().
> tab=array(1:24,dim=c(4,3,2)) > tab , , 1 [,1] [,2] [,3] [1,] 1 5 9 [2,] 2 6 10 [3,] 3 7 11 [4,] 4 8 12 , , 2 [,1] [,2] [,3] [1,] 13 17 21 [2,] 14 18 22 [3,] 15 19 23 [4,] 16 20 24 > dimnames(tab)=list(c("a","b","c","d"),c("aa","bb","cc"),c("aaa","bbb")) > tab , , aaa aa bb cc a 1 5 9 b 2 6 10 c 3 7 11 d 4 8 12 , , bbb aa bb cc a 13 17 21 b 14 18 22 c 15 19 23 d 16 20 24 |
Modyfikowanie nazw poszczególnych wymiarów może być wykonane poprzez modyfikację listy dimnaes(). Usunięcie nazw może zostać zrealizowane poprzez dimnames(macierz wielowymiarowa)=NULL.
Funkcje i działania na macierzach wielowymiarowych
Macierze wielowymiarowe analizowane są przez funkcje mode(), typeof(), class() i str() dając następujące odpowiedzi:
> tab=array(1:24,dim=c(4,3,2)) > mode(tab) [1] "numeric" > typeof(tab) [1] "integer" > class(tab) [1] "array" > str(tab) int [1:4, 1:3, 1:2] 1 2 3 4 5 6 7 8 9 10 ... > tab=array(letters[1:24],dim=c(4,3,2)) > mode(tab) [1] "character" > typeof(tab) [1] "character" > class(tab) [1] "array" > str(tab) chr [1:4, 1:3, 1:2] "a" "b" "c" "d" "e" "f" "g" "h" "i" ... |
Funkcja str() zastosowana do tablicy z nazwanymi elementami na wymiarach, dodaje te informacje do wyników, jako atrybut obiektu.
> tab=array(1:24,dim=c(4,3,2)) > str(tab) int [1:4, 1:3, 1:2] 1 2 3 4 5 6 7 8 9 10 ... > tab=array(1:24,dim=c(4,3,2), + dimnames=list(c("a","aa","aaa","aaaa"),c("b","bb","bbb"),c("c","cc"))) > str(tab) chr [1:4, 1:3, 1:2] "a" "b" "c" "d" "e" "f" "g" "h" "i" ... - attr(*, "dimnames")=List of 3 ..$ : chr [1:4] "a" "aa" "aaa" "aaaa" ..$ : chr [1:3] "b" "bb" "bbb" ..$ : chr [1:2] "c" "cc" |
Podstawowe funkcje związane z tablicami pokazują ich budowę i strukturę. Są to:
- dim(tablica) – liczba elementów poszczególnych wymiarów macierzy wielowymiarowej.
- nrow(tablica) – liczba elementów pierwszego wymiaru macierzy wielowymiarowej.
- ncol(tablica) – liczba elementów drugiego wymiaru macierzy wielowymiarowej.
- length(tablica) – liczba elementów w macierzy wielowymiarowej.
- dimnames(tablica) – nazwy poszczególnych wymiarów macierzy wielowymiarowej.
> tab=array(1:24,dim=c(4,3,2),dimnames=list(letters[1:4],c("K1","K2","K3"),c("pierwszy","drugi"))) > dim(tab) [1] 4 3 2 > ncol(tab) [1] 3 > nrow(tab) [1] 4 > length(tab) [1] 24 > dimnames(tab) [[1]] [1] "a" "b" "c" "d" [[2]] [1] "K1" "K2" "K3" [[3]] [1] "pierwszy" "drugi" > mode(tab) [1] "numeric" > str(tab) int [1:4, 1:3, 1:2] 1 2 3 4 5 6 7 8 9 10 ... - attr(*, "dimnames")=List of 3 ..$ : chr [1:4] "a" "b" "c" "d" ..$ : chr [1:3] "aa" "bb" "cc" ..$ : chr [1:2] "aaa" "bbb" |
Utworzona macierz wielowymiarowa jest jednym obiektem, ale po jej wywołaniu widzimy tylko jej dwuwymiarowe przekroje. Standardowo przekroje te pojawiają się dla pierwszego (rzędy) i drugiego wymiaru (kolumny). Sposób wyświetlania takiej macierzy można zmienić przez zastosowanie funkcji aperm() i opcji perm. Jako wartość tej opcji należy podać w jaki sposób zmieniany jest porządek wymiarów (standardowo 1:d, gdzie d jest wymiarem tablicy). Zatem musi to być ciąg złożony z liczb {1,2,…,d} zapisanych w innej kolejności (np. c(2,1,5,4,3) dla d=5).
> tab=array(1:24,dim=c(4,3,2)) > tab , , 1 [,1] [,2] [,3] [1,] 1 5 9 [2,] 2 6 10 [3,] 3 7 11 [4,] 4 8 12 , , 2 [,1] [,2] [,3] [1,] 13 17 21 [2,] 14 18 22 [3,] 15 19 23 [4,] 16 20 24 > aperm(tab, perm=c(2,1,3)) , , 1 [,1] [,2] [,3] [,4] [1,] 1 2 3 4 [2,] 5 6 7 8 [3,] 9 10 11 12 , , 2 [,1] [,2] [,3] [,4] [1,] 13 14 15 16 [2,] 17 18 19 20 [3,] 21 22 23 24 > aperm(tab, perm=c(1,3,2)) , , 1 [,1] [,2] [1,] 1 13 [2,] 2 14 [3,] 3 15 [4,] 4 16 , , 2 [,1] [,2] [1,] 5 17 [2,] 6 18 [3,] 7 19 [4,] 8 20 , , 3 [,1] [,2] [1,] 9 21 [2,] 10 22 [3,] 11 23 [4,] 12 24 |
Między tablicami a wektorami możliwe są standardowe działania +, *, -, /, i ^, przy czym obowiązują tu takie same zasady jak podczas działań na tablicach i wektorach. Wektory są skracane lub wydłużane do liczby elementów w tablicy i między odpowiadającymi sobie liczbami wykonywane są działania.
> tab=array(1:24,dim=c(4,3,2)) > tab , , 1 [,1] [,2] [,3] [1,] 1 5 9 [2,] 2 6 10 [3,] 3 7 11 [4,] 4 8 12 , , 2 [,1] [,2] [,3] [1,] 13 17 21 [2,] 14 18 22 [3,] 15 19 23 [4,] 16 20 24 > tab+1:7 , , 1 [,1] [,2] [,3] [1,] 2 10 11 [2,] 4 12 13 [3,] 6 14 15 [4,] 8 9 17 , , 2 [,1] [,2] [,3] [1,] 19 20 28 [2,] 21 22 23 [3,] 16 24 25 [4,] 18 26 27 Komunikat ostrzegawczy: W poleceniu 'tab + 1:7': długość dłuszego obiektu nie jest wielokrotnością długości krótszego obiektu |
Funkcje statystyczne na tablicach działają tak samo jak na wektorach tworzonych przez elementy tablicy.
> tab=array(1:24,dim=c(4,3,2)) > sum(tab) [1] 300 > mean(tab) [1] 12.5 > sd(tab) [1] 7.071068 > var(tab) [1] 50 |