Pakiet R w analizie układów złożonych

LABORATORIUM 3

Funkcje obsługi macierzy

Czę¶ć funkcji pozanych wcze¶niej przy obsłudze wektorów można zastosować także do macierzy, przy czym w przypadku which.min() oraz which.max() konieczne jest użycie dodatkowo funkcji arrayInd() do okre¶lenia indeksów macierzy - w przeciwnym wypadku otrzymamy tylko indeks "wektorowy".

# PRZYKŁAD 3.1
A <- matrix(1:16, 4, 4)
A
##      [,1] [,2] [,3] [,4]
## [1,]    1    5    9   13
## [2,]    2    6   10   14
## [3,]    3    7   11   15
## [4,]    4    8   12   16
sum(A)
## [1] 136
mean(A)
## [1] 8.5
sd(A)
## [1] 4.760952
min(A)
## [1] 1
max(A)
## [1] 16
which.min(A)
## [1] 1
which.max(A)
## [1] 16
arrayInd(which.min(A), dim(A))
##      [,1] [,2]
## [1,]    1    1
arrayInd(which.max(A), dim(A))
##      [,1] [,2]
## [1,]    4    4

Funkcja APPLY

Aby wyznaczyć brzegowe warto¶ci dla macierzy (np. sumę, ¶redni± etc) wykorzystuje się funkcję apply(macierz,liczba,funkcja), przy liczba okre¶la, czy odnosimy się do wiersza (1), kolumny (2) itd.

# PRZYKŁAD 3.2
apply(A, 1, sum)
## [1] 28 32 36 40
apply(A, 2, sum)
## [1] 10 26 42 58
apply(A, 1, mean)
## [1]  7  8  9 10
apply(A, 2, sd)
## [1] 1.290994 1.290994 1.290994 1.290994

Zamiast wbudowanych funkcji można także wykorzystać własne funkcje

# PRZYKŁAD 3.3

# Własna funkcja
f <- function(x) {
  sum(x^2)
}

apply(A, 1, f)
## [1] 276 336 404 480
apply(A, 2, f)
## [1]  30 174 446 846

Funkcja SAPPLY

Jak już zostało wcze¶niej wspomniane, w R należy unikać stosowania pętli. Paradygmat jest następuj±cy: wszędzie, gdzie się da, należy wykorzystywać wektory (lub listy, macierze, ramki danych) i na tych strukturach dokonywać okre¶lonych operacji, dostaj±c na wyj¶ciu znów wektor etc. W najprostszym przypadku oznacza to po prostu użycie znanej funkcji (np. sin()) do wszytskich elementów wektora:

# PRZYKŁAD 3.4

x <- 10
sin(x)
## [1] -0.5440211

Powyższy przykład można również zapisać za pomoc± funkcji sapply, która jako argumenty przyjmuje wektor oraz funkcję, która zostanie zastosowana element po elemencie:

# PRZYKŁAD 3.5

x <- 10
sapply(x, sin)
## [1] -0.5440211

Oczywi¶cie, w tym konkretnym przypadku wygodniej jest użyć opcji z Przykładu 3.4. Gdy jednak sami chcemy skonstruowac funkcję, musi uciec się do sapply, w przeciwnym wypadku R będzie chciał wykonać nasz± funkcję tylko dla pierwszego elementu

# PRZYKŁAD 3.6
# Własna funkcja
g <- function(x) {
  
  y <- sum(1:x)
  if(y > 2 * mean(x)) return(x)
  else return(0)
  
}

# Główny kod
x <- 1:10

# Bezpo¶rednie użycie g do wektora
g(x)
## Warning in 1:x: numerical expression has 10 elements: only the first used
## [1] 0
# Użycie sapply
sapply(x, g)
##  [1]  0  0  0  4  5  6  7  8  9 10

Funkcje anonimowe

Podobnie jak w innych językach skryptowych istnieje możliwo¶ć tworzenia funkcji anonimowych. S± to najczęsciej krótkie wyrażenia, nie tylko arytmetyczne, bez nazwy (st±d anonimowe), które istniej± ulotnie - po wykonaniu operacji zostaj± usunięte z pamięci

# PRZYKŁAD 3.7
a <- 1:10
sapply(a, function(x) x^2 - 2)
##  [1] -1  2  7 14 23 34 47 62 79 98

Za pomoc± funkcji anonimowych oraz zagnieżdżonych funkcji sapply można tworzyć alternatywa dla pętli

# PRZYKŁAD 3.8

a <- 1:10
sapply(a, function(x) {sapply(rev(a), function(y) x * y)})
##       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
##  [1,]   10   20   30   40   50   60   70   80   90   100
##  [2,]    9   18   27   36   45   54   63   72   81    90
##  [3,]    8   16   24   32   40   48   56   64   72    80
##  [4,]    7   14   21   28   35   42   49   56   63    70
##  [5,]    6   12   18   24   30   36   42   48   54    60
##  [6,]    5   10   15   20   25   30   35   40   45    50
##  [7,]    4    8   12   16   20   24   28   32   36    40
##  [8,]    3    6    9   12   15   18   21   24   27    30
##  [9,]    2    4    6    8   10   12   14   16   18    20
## [10,]    1    2    3    4    5    6    7    8    9    10

Tworzenie wykresów

Standardow± funkcj± wykorzystywan± do tworzenia wykresów jest plot(x,y), gdzie x i y s± odpowiednio wektorami liczb.

# PRZYKŁAD 3.9
x <- 1:10
plot(x, x^2)

Funkcja plot() ma pokaĽny zestaw różnych opcji, przy czym najczę¶ciej wykorzystywane to xlab="..." (tytuł osi X), ylab="..." (tytuł osi Y), main="..." (tytuł wykresu), col="..." (kolor punktów), pch=... (kształt punktów), cex="..." (rozmiar punktów), font=... (typ czcionki osi: 1 - normalna, 2 - pogrubiona, 3 - kursywa, 4 - pogrubiona kursywa). W przypadku nazw osi można wykorzystywać funkcję expression(), która koduje wyrażenia matematyczne i litery greckie (np. ^ to indeks górny, [..] - indeks dolny, itd.).

# PRZYKŁAD 3.10
x <- 1:10
plot(x, x^2, xlab = "x", ylab = expression(f(xi)==x^2), col = "red", pch = 19, font = 2, font.lab = 4, main = "Wykres funkcji f(x)", font.main = 3, cex = 2)

W przypadku potrzeby zapisania wykresu do pliku należy skorzystać z jednej z komend png(), jpeg() czy tiff(), a następnie zamkn±c strumień komend± dev.off().

# PRZYKŁAD 3.11

png("fig2.png")
plot(x, x^2, xlab = "x", ylab = expression(f(xi)==x^2), col = "red", pch = 19, font = 2, font.lab = 4, main = "Wykres funkcji f(x)", font.main = 3, cex = 2)
dev.off()
## png 
##   2

Tworzenie histogramów

Najprostsz± metod± tworzenia histogramu (w formie tekstowej) jest wykorzystanie funkcji tabulate(), przy efektem jej działania jest zliczenie warto¶ci całkowitych zawartych w wektorze. W przypadku liczb rzeczywistych doknywane jest zaokr±glenie w dół.

# PRZYKŁAD 3.12

y <- c(0,0,1,2,3,1,2,3,4)
tabulate(y)
## [1] 2 2 2 1
y <- c(0,0,1.1,1.9,2.1,2,3)
tabulate(y)
## [1] 2 2 1

W przypadku histogramu 2D można posłużyć się funkcj± table(), która stworzy dwuwymiarow± tablicę współwystępowania warto¶ci.

# PRZYKŁAD 3.13

df <- data.frame(x=c(1,1,2,2,3,4,5), y=c(2,2,3,1,5,5,5))
df
##   x y
## 1 1 2
## 2 1 2
## 3 2 3
## 4 2 1
## 5 3 5
## 6 4 5
## 7 5 5
table(df)
##    y
## x   1 2 3 5
##   1 0 2 0 0
##   2 1 0 1 0
##   3 0 0 0 1
##   4 0 0 0 1
##   5 0 0 0 1

Jednak klasyczn± funkcj± odpwiedzialn± za tworzenie histogramów jest hist(). Samo jej wywołanie daje efekt wyrysowania histogramu o zadanej liczbie przedziałów (binów).

# PRZYKŁAD 3.14
x <- c(1,1,1,2,2,4,10)
hist(x)

W pewnym sensie nawet ważniejsz± rzecz± od samego wykresu jest zawarto¶ć zmiennej, do której zostanie zapisany jego wynik. Otrzymamy z niej informacje nie tylko o liczbie zliczeń (counts), ale także o granicach binów (breaks), ich ¶rodkach (mids) jak również funkcji gęsto¶ci (density).

# PRZYKŁAD 3.15
x <- c(1,1,1,2,2,4,10)
h <- hist(x)

h
## $breaks
## [1]  0  2  4  6  8 10
## 
## $counts
## [1] 5 1 0 0 1
## 
## $density
## [1] 0.35714286 0.07142857 0.00000000 0.00000000 0.07142857
## 
## $mids
## [1] 1 3 5 7 9
## 
## $xname
## [1] "x"
## 
## $equidist
## [1] TRUE
## 
## attr(,"class")
## [1] "histogram"

Losowanie warto¶ci

Funkcja SAMPLE

Za pomoc± funkcji sample(x) można w pakiecie R uzyskać permutację oryginalnego zbioru (wektora x). W przypadku podania konkretnej liczby próbek, mniejszej niż rozmiar x elementy zostan± wylosowane bez zwracania. Wreszcie podanie opcji replace=TRUE umożliwi losowanie ze zwracaniem. Dodatkowo, podanie wektora prob daje możliwo¶ć sterowania prawdopodobieństwem wylosowania konkretnych elementów wektora x. Funkcja nie ogranicza się jedynie do typów liczbowych.

# PRZYKŁAD 3.15

sample(1:3, 2)
## [1] 1 2
sample(1:10, 2)
## [1] 2 8
sample(1:10)
##  [1] 10  6  4  1  2  5  9  3  8  7
sample(1:10, 4)
## [1]  5  3  8 10
sample(1:10, 20, replace=TRUE)
##  [1]  9  9  5  7  1  5  9  3 10  9  6  1  5  9  7  4  3  8  8  8
sample(1:3, 10, replace=TRUE, prob=c(0.1,0.8,0.1))
##  [1] 2 2 3 2 2 2 2 1 2 2
sample(letters[1:3], 10, replace=TRUE)
##  [1] "a" "b" "a" "b" "b" "b" "b" "c" "c" "a"
sample(c(0.1, 0.2, 0.3), 10, replace=TRUE)
##  [1] 0.3 0.2 0.2 0.1 0.3 0.2 0.1 0.2 0.2 0.2

Rozkłady prawdopodobieństw

W pakiecie R jest zaimplementowany cały zestaw standardowych rozkładów prawdopodobieństw (rozkład Gaussa, dwumianowy etc), do których odwołujemy się w ten sam sposób r|p|dnazwa(), gdzie r oznacza losowanie z rozkładu (np. runif() - losowanie liczby z rozkładu jednostajnego), p oznacza dystrybuantę (np. pnorm(2, 0, 1.5) - warto¶ć dystrybuanty dla rozkładu normalnego o ¶redniej 0 i odchyleniu 1.5 w punkcie 2), d - gęsto¶ć prawdopodobieństwa (np. dexp(2, 0.1) - gęsto¶ć prawdopodobieństwa dla rozkładu wykładniczego o parameterze 0.1 w punkcie 2), natomiast nazwa to nazwa odpowiedniej funkcji.

# PRZYKŁAD 3.16

x <- seq(-2, 2, .1)
plot(x, dnorm(x, 0, 0.5), ylim = c(0,1.5), pch = 19)
points(x, dnorm(x, 0, 1), pch = 19, col = "blue")
points(x, dnorm(x, 0, 0.3), pch = 19, col = "green", t = "o")
lines(x, pnorm(x, 0, 0.3), col = "red", lwd = 2)

# PRZYKŁAD 3.17

runif(10)
##  [1] 0.4958424 0.6924246 0.4550775 0.3537938 0.9271655 0.4203290 0.5741039
##  [8] 0.6672020 0.7669128 0.5813111
runif(10, 5, 10)
##  [1] 6.440368 7.655271 8.463800 7.559935 6.400319 9.589384 6.555402
##  [8] 8.183997 5.728884 7.352384