1 Macierze
Macierze, podobnie jak wektory, mogą zawierać elementy dowolnego, ale
tego samego typu (nie można utworzyć macierzy zawierającej jednocześnie
np. wartości liczbowych i tekstowych).
Podstawowa polecenie służące tworzeniu macierzy to
matrix(vec, nrow=n, ncol=p, byrow=T),
gdzie vec jest wektorem zawierającym kolejne elementy
macierzy, które standardowo będą rozmieszczone kolumnami. W celu
rozmieszczenia elementów wierszami należy wybrać opcję
byrow=T.
1.1 Tworzenie
macierzy
1.2 Wybrane operacje na
macierzach
Przetestować działanie poniższych poleceń
x3=t(x2)
#Transpozycja macierzy x2
b=x1*x2
#Iloczyn macierzy element po elemencie
b=x3%*%x2
#Standardowy iloczyn macierzy
dim(b)
#Podaje wymiar macierzy
b[3,2]
#Wybranie elementu b32 macierzy b
b[3,2]=5
#Przypisanie wartości do elementu macierzy
b[,2]
#Wybranie drugiej kolumny macierzy b
b[c(3,4),]
#Wybranie wiersza 3 i 4 macierzy b
b[-2,]
#Wybranie wszystkich wierszy macierzy b poza drugim
wierszem
b[,-c(2,4)]
#Wybranie wszystkich kolumn macierzy b poza drugą i
czwartą
b[1,]>600
# Wykonanie testu na pierwszym wierszu macierzy
ind=which(b[1,]>600)
b[,ind]
#Wybranie tych kolumn macierzy b , których pierwszy
element
jest większy niż 600 (jako wynik wcześniejszego polecenia)
rbind(x1,x2)
#Połączenie wierszowe macierzy, czyli utworzenie macierzy,
której wierszami są kolejne wiersze macierzy x1,
a następnie macierzy x2. Polecenie to pozwala na
dołączanie kolejnych wierszy do macierzy, efektem jest macierz postaci
blokowej:\[
\left[
\begin{array}{c}
x_1\\x_2
\end{array}
\right]
\]
cbind(x1,x2)
#Poziome, “kolumnowe” połączenie dwóch macierzy, czyli utworzenie
macierzy, w której (licząc od lewej) najpierw są kolumny macierzy
x1,
a następnie kolumny macierzy x2. W postaci blokowej:
\[\left[
\begin{array}{c c}
x_1 & x_2
\end{array}
\right]
\]
apply(x1,2,sum)
#Funkcja apply pozwala na zastosowanie funkcji
działającej
na wektorach do macierzy x1 (w tym przypadku sumy)
do kolumn (drugi argument jest tutaj równy 2) lub wierszy (drugi
argument byłby równy 1). W wyniku dostajemy wektor zawierający sumy
elementów
poszczególnych kolumn macierzy x1
apply(x1,1,sum)
#Jak wyżej, tylko tym razem otrzymujemy sumy elementów
wierszami macierzy x1
apply(x1,1,max)
#Otrzymujmy wektor zawierający element maksymalny
każdego z wierszy macierzy x1
1.3 Zadania -
macierze
1.3.1 Zadanie
Utworzyć wektor x=(2;2;2;2;2) za pomocą funkcji
rep oraz wektor y=(-1;0;1;2;3) za pomocą
funkcji seq.
Utworzyć macierz A o 5 wierszach i 2 kolumnach,
w której pierwsza kolumna składa się z elementów wektora x
a druga z elementów wektora y .
Zmienić drugi wiersz macierzy A na wiersz
postaci (2;4)
1.3.2 Zadanie
- Utworzyć macierz
\(\mathbf{A}=\left( \begin{array}{ccc}
2&23&8\\10&6&90\\4&7&12\end{array}\right)\)
za pomocą poleceń cbind i/lub matrix. Czy da
się utworzyć tą macierz za pomocą polecenia rbind?
- Obliczyć średnią oraz iloczyn elementów w wierszach i kolumnach
macierzy A za pomocą funkcji
apply,
sum oraz prod.
- Obliczyć sumę wszystkich liczb z dwóch pierwszych wierszy macierzy
A, a następnie sumę wszystkich liczb z pierwszej i
trzeciej kolumny
- Co zwracają polecenia
t(A), det(A) i
diag(A)? Wyznaczyć ślad macierzy A.
- Co zwracają polecenia
A^2, A*A,
A%*%A?
- Co zwracają polecenia
1/A, A^(-1),
solve(A)?
- Rozwiązać układ równań
\(\left\{ \begin{array}{ccc}
2x+23y+8z&=&5\\ 10x+6y+90z&=&6\\ 4x+7y+12z&=&7
\end{array} \right.\)
- Wybrać te wiersze macierzy A, w których suma
elementów jest większa niż 30.
2 Ramki danych
Ramki danych (data.frame) są tablicami, których kolumny mogą być
niejednorodne. Przykładowo, ramka może zawierać zarówno kolumny znakowe
jak i numeryczne, ale każda kolumna zawiera elementy tego samego
rodzaju. Jest to najważniejsza klasa obiektów dedykowana specjalnie do
przechowywania danych.
Przykładowo, w ramce danych możemy umieścić zmienne jakościowe
opisywane za pomocą znaków (np. kolumnę opisującą płeć M/K osoby lub jej
status społeczno-zawodowy) oraz zmienne ilościowe opisywane za pomocą
liczb (np. wzrost lub wiek). Wiele narzędzi statystycznych dostępnych w
R jest dedykowanych tej klasie obiektów. Ramki danych tworzone są też
zazwyczaj przez R podczas importu danych.
Ramki danych mogą być utworzone poprzez zgrupowanie wektorów
var1, var2,… o tej samej długości
poleceniem
data.frame(nazwa1=var1, nazwa2=var2,…)
Możliwe jest też przekształcenie macierzy w ramkę danych za pomocą
polecenia as.data.frame.
2.1 Tworzenie ramek
danych i podstawowe operacje na ramkach
v1=sample(1:12,30,rep=T)
#Losuje ze zbioru {1…12} ciąg 30 liczb z powtórzeniami
v2=sample(LETTERS[1:10],30,rep=T)
#Losuje ze zbioru liter {A,B,…J} ciąg 30 liter z powtórzeniami
v3=runif(30)
#30 niezależnych realizacji rozkładu jednostajnego na przedziale
[0,1]
hist(v3)
#Rysuje histogram zmiennej v3
v4=rnorm(30)
#30 niezależnych realizacji rozkładu normalnego o średniej 0 i
wariancji 1
hist(v4)
#Rysuje histogram zmiennej v4
xx=data.frame(Age=v1,Firstname=v2,Height=v3,Weight=v4)
#Tworzy ramkę danych z 4 zmiennymi i 30 osobnikami/obserwacjami
str(xx)
#Wyświetla strukturę obiektu
xx$Firstname
#Do zmiennych możemy się odnosić poprzez $ i nazwę
xx[,1]
#Do zmiennych możemy się odnieść przez [ ], tak jak w
przypadku macierzy
xx$Firstname[3]
#Dostęp do trzeciego elementu wektora xx$Firstname
xx[3,2]
#To samo co wyżej
summary(xx)
#Podstawowe statystyki dla zmiennych
str(xx)
#Struktura obiektu może się różnić w zależności od występujących
zmiennych ilościowych i jakościowych
ma=matrix(1:15,nrow=3); ma
#Tworzy nową macierz
ma=as.data.frame(ma)
#Zmienia macierz na ramkę danych
ma
#Wyświetlenie ramki
str(ma)
#Struktura ramki
names(ma)=c('VA','VB','VC','VD','VE')
#Przypisanie nazw zmiennym (kolumny ramki)
row.names(ma)=c('l1','l2','l3')
#Przypisanie nazw obserwacjom (wiersze ramki)
ma
#Wyświetlenie ramki
2.2 Działania na
zmiennych jakościowych (i ilościowych)
sex=sample(c('M','F'),100,rep=T)
Wygenerowanie 100 realizacji zmiennej “sex” o wartościach “M” i “F”
(mężczyzna, kobieta)
height=rnorm(100,mean=170,sd=10)
Wygenerowanie 100 realizacji zmiennej “height” z rozkładu normalnego
o średniej “mean=170” i odchyleniu standardowym “sd=10”
height[which(sex=='M')]=height[which(sex=='M')]+10
Dodanie do zmiennej “height” wartości 10, o ile zmiennej “sex”
odpowiada wartość “M” - inaczej, mężczyźni statystycznie są wyżsi
tapply(height,sex,mean)
Obliczenie średniej zmiennej “height” osobno dla “M” i “F”
tapply(height,sex,sd)
Obliczenie odchylenia standardowego zmiennej “height” osobno dla “M”
i “F”
2.3 Gotowe zestawy
danych
W R istnieją pewne gotowe zestawy danych, które można wykorzystać do
ćwiczeń
data()
Otwiera okno tekstowe z listą wszystkich tabel danych dostępnych w
R
women
Wyświetla tabelę z danymi “women”
? women
Wyświetla opis ramki danych “women”. Dowiemy się, że wzrost jest w
calach, a waga w funtach.
names(women)
Nazwy zmiennych w “women”
attributes(women)
Pewna charakterystyka “women”, w tym nazwy zmiennych, typ danych i
nazwy obserwacji
women$height
Wyświetla wartości zmiennej “height” dla ramki
women
apply(women,1,sum)
Funkcję “apply” można stosować do ramek danych
apply(women,2,max)
Funkcję “apply” można stosować do ramek danych
2.4 Zadania - Ramki
danych
2.4.1 Zadanie
W ćwiczeniu wykorzystamy zbiór danych “iris” dostępny w R
Sprawdzić, czy jest to obiekt typu data.frame (ramka
danych)
Co znajduje się w zbiorze danych?
Wpisz polecenie summary(iris). Ile osobników gatunku
versicolor znajduje się w tej bazie danych? Jaka jest średnia
zmiennej Sepal.Width? Jaka jest najmniejsza wartość?
Utwórz ramkę danych o nazwie “iris2”, który zawiera tylko
osobniki gatunku “setosa”.
Posortuj osobniki gatunku “setosa” według długości
działki kielicha (eng. sepal)
Znajdź średnie zmiennych Sepal.Length, Sepal.Width,
Petal.Lehgth oraz Petal.Width przy użyciu funkcji
apply oraz mean.
Znajdź średnie zmiennej Sepal.Length dla każdego z
trzech gatunków używając funkcji tapply oraz
mean.
2.4.2 Zadanie
Poniższa tabela przedstawia liczbę studentów przyjętych w pięciu
miastach z podziałem na 5 typów kierunków: nauki humanistyczne, ścisłe,
medyczne, sportowe i techniczne w 2006 roku:
n. human.
n. ścisłe
medyczne
sportowe
techniczne
Bordeaux
12220
6596
7223
357
2239
Lyon
15310
6999
10921
395
3111
Paryż
112958
40244
46146
1247
7629
Rennes
8960
6170
4661
279
4013
Tuluza
12125
8233
6653
553
3178
Stworzyć ramkę danych zawierających dane z powyższej tabeli. W
szczególności należy uzupełnić nazwy kolumn i wierszy jak wyżej
(polecenia names i row.names)
Obliczyć całkowita liczbę studentów w danym mieście, a następnie
uporządkować tabelę w porządku rosnącym względem tej liczby
Obliczyć całkowita liczbę studentów danego typu kierunków, a
następnie uporządkować tabelę w porządku rosnącym względem tej
liczby
Utworzyć nowa ramkę danych zawierającą tylko te miasta, gdzie
liczba przyjętych na kierunki ścisłe jest wyższa niż liczba przyjęć na
kierunki medyczne (jedno polecenie/jedna linijka)
2.5 Zadanie - metoda
D’Hondta podziału mandatów w systemach wyborczych
2.5.1 Wstęp
Weźmiemy pod uwage wyniki wyborów do Sejmu RP z 15 października 2023,
dane dla okręgu nr 13 (Kraków i okolice) dostępne na stronie
W tym okręgu do obsadzenia jest 14 mandatów, próg wyborczy 5%
przekroczyło 5 komitetów wyborczych i tylko te komitety bierzemy pod
uwagę:
partie=c("KO","PiS", "3Droga","Lewica", "Konfederacja")
glosy =c(232799,232430,127693,83633,58435)
l_mandatow=14
Gdyby zastosować wprost proporcjonalność zdobytych mandatów do liczby
otrzymanych głosów dostalibyśmy wyniki ułamkowe:
#proporcjonalny podział głosów prowadzi do ułamkowych mandatów
razemglosy=sum(glosy)
udzial=glosy/razemglosy
ulamkowe_mandaty=l_mandatow*udzial
ulamkowe_mandaty
## [1] 4.434327 4.427298 2.432281 1.593031 1.113063
i taki wynik byłby trudny do zinterpretowania.
2.5.2 Metoda
D’Hondta
Metoda ta jest algorytmem umożliwiającym niejako rozparcelowanie
ułamkowych mandatów między komitety wyborcze. Opis algorytmu można
znaleźć na
W skrócie algorytm polega na zbudowaniu tabelki jak niżej, gdzie w
pierwszym wierszu umieszczamy liczby głosów uzyskane przez poszczególne
komitety, a następne wiersze powstają przez podzielenie (zawsze)
pierwszego wiersza przez kolejne liczby naturalne. Ilość wierszy takiej
tabelki odpowiada liczbie mandatów do rozdzielenia (istnieje możliwość,
że ktoś zgarnie wszystkie mandaty).
Następnie z tabelki wybieramy najwyższe wyniki aż do wyczerpania
liczby mandatów do obsadzenia w okręgu.
2.5.3 Zadanie właściwe -
część pierwsza
Zbudować ramkę danych - tabelkę wyników z ilorazami wynikającymi z
metody d’Hondta. Efekt powinien przypominać
## KO PiS 3Droga Lewica Konfederacja
## 1 232799.00 232430.00 127693.000 83633.000 58435.000
## 2 116399.50 116215.00 63846.500 41816.500 29217.500
## 3 77599.67 77476.67 42564.333 27877.667 19478.333
## 4 58199.75 58107.50 31923.250 20908.250 14608.750
## 5 46559.80 46486.00 25538.600 16726.600 11687.000
## 6 38799.83 38738.33 21282.167 13938.833 9739.167
## 7 33257.00 33204.29 18241.857 11947.571 8347.857
## 8 29099.88 29053.75 15961.625 10454.125 7304.375
## 9 25866.56 25825.56 14188.111 9292.556 6492.778
## 10 23279.90 23243.00 12769.300 8363.300 5843.500
## 11 21163.55 21130.00 11608.455 7603.000 5312.273
## 12 19399.92 19369.17 10641.083 6969.417 4869.583
## 13 17907.62 17879.23 9822.538 6433.308 4495.000
## 14 16628.50 16602.14 9120.929 5973.786 4173.929
W powyższej ramce nazwy kolumn to komitety wyborcze, a nazwy wierszy
to kolejne dzielniki.
Wskazówki:
liczba głosów/wektor dzielników daje wektor ilorazów
wektory można połączyć w macierz za pomocą
cbind
przydatne: as.data.frame, colnames,
rownames
Z powyższej ramki danych należałoby wybrać 14 największych liczb (14,
bo taka jest liczba mandatów w okręgu 13). Niestety, sortowanie macierzy
jest nieco mało wygodne, w celu zautomatyzowania obliczeń zbudujemy
inną, “lepszą” ramkę danych:
2.5.4 Zadanie właściwe -
część druga
Ponieważ łatwiej posortować wektor, zbudujemy ramkę danych
postaci:
## partia ilorazy
## 1 KO 232799.00
## 2 KO 116399.50
## 3 KO 77599.67
## 4 KO 58199.75
## 5 KO 46559.80
## 6 KO 38799.83
## partia ilorazy
## 65 Konfederacja 6492.778
## 66 Konfederacja 5843.500
## 67 Konfederacja 5312.273
## 68 Konfederacja 4869.583
## 69 Konfederacja 4495.000
## 70 Konfederacja 4173.929
gdzie pierwsza kolumna to kolejno sklonowane nazwy komitetów
wyborczych (w liczbie równej liczbie mandatów), a druga kolumna to
kolejne zestawy ilorazów.
Wskazówka: Ramkę tego typu możemy zbudować od
podstaw albo korzystając z ramki z pierwszej części i funkcji
stack().
Mając ramkę jak powyżej należy:
posortować malejąco kolumnę ilorazów ( order(), czy
może sort() będzie lepszy?)
wybrać pierwsze 14 wyników (odpowiadających liczbie
mandatów)
wybrać nazwy komitetów odpowiadających 14 najlepszym
wynikom/ilorazom
zliczyć liczbę mandatów za pomocą table()
Powinniśmy dostać coś podobnego jak niżej, gdzie wyniki
table() zostały jeszcze raz posortowane
##
## KO PiS 3Droga Konfederacja Lewica
## 5 5 2 1 1
## [1] 4.434327 4.427298 2.432281 1.593031 1.113063
Mamy też porównanie z ułamkowymi mandatami, widzimy gdzie te ułamkowe
części się poprzesuwały.
Można też sprawdzić, czy wyliczony przez nas podział zgadza się z
oficjalnymi wynikami
2.5.5 Zadanie właściwe -
część trzecia
Powtórzyć podział mandatów dla innego, wybranego okręgu i porównać z
oficjalnymi wynikami.
2.5.6 Zadanie dodatkowe
1
Sprawdzić, jak wyglądałby podział mandatów, gdyby komitety zawarły
koalicje, np. jakbyśmy zsumowali głosy KO+Lewica+3droga i
PiS+Konfederacja.
2.5.7 Zadanie dodatkowe 2
- metoda Sainte-Laguë
Innym sposobem podziału mandatów jest wykorzystanie metody
Sainte-Laguë. Różnica w stosunku do metody D’Hondta polega na tym, że
dzielniki to kolejne liczby nieparzyste.
Więcej informacji na Wikipedia
metoda Sainte-Laguë
Zadanie:
zmodyfikować kod tak, aby obliczał liczbę mandatów metodą
Sainte-Laguë
porównać otrzymane wyniki z metody Sainte-Laguë oraz metody
D’Hondta
Możliwe jest, że w niektórych okręgach liczby mandatów otrzymanych za
pomocą obu metod będą różne (metoda D’Hondta bardziej sprzyja większym
partiom)
2.5.8 Ciekawostka
W polskim systemie wyborczym, gdy znamy już liczbę mandatów
przypadającą danemu komitetowi, bierzemy pod uwagę indywidualne wyniki
kandydatów z danej listy.
Stąd też “układanki wyborcze”, tak aby znane nazwisko zdobyło nie
tylko mandat dla siebie, ale znacznie poprawiło ogólny wynik listy, co
daje większą liczbę mandatów.
3 Listy
Lista jest uporządkowanym zbiorem obiektów, nie koniecznie tego
samego typu. Elementami list mogą być dowolne obiekty zdefiniowane w R.
Można utworzyć na przykład listę, która zawiera wektor liczbowy i
macierz znaków. Własność ta jest wykorzystywana w szczególności przez
niektóre funkcje do zwracania złożonych wyników w formie pojedynczego
obiektu. Listę tworzy się za pomocą funkcji
list(nazwa1=el1, nazwa2=el2,…). Do każdego elementu listy
można przejść używając jego indeksu w nawiasach podwójnych
[[…]] lub jego nazwy poprzedzonej znakiem
$.
li=list(num=1:5,y="color",a=TRUE)
utworzenie listy z 3 obiektami
li
wyświetlenie listy
li$num
dostęp do elementu listy przez $
li$a
dostęp do elementu listy przez $
li[[1]]
dostęp do elementu listy przez [[…]]
li[[3]]
dostęp do elementu listy przez [[…]]
a=matrix(c(6,2,0,2,6,0,0,0,36),nrow=3)
utworzenie macierzy
eigen(a)
obliczenie rozkładu Jordana macierzy
res=eigen(a)
Wynik podawany jest w postaci listy
attributes(res)
Pozwala na wyświetlenie nazw elementów listy
str(res)
Wyświetla strukturę listy
res$values
Wyświetlenie wartości własnych
res$vectors
Wyświetlenie wektorów własnych
res$vectors[,1]
Wyświetlenie pierwszego wektora własnego
diag(res$values)
Macierz Jordana (dokładniej macierz diagonalna, której elementy ma
przekątnej pochodzą z wektora zawierającego wartości własne)
res$vectors%*%diag(res$values)%*%t(res$vectors)
Rozkład Jordana, macierz odwrotna = transponowana
x<-list(a=1:10,beta=exp(-3:3),logic=c(TRUE,FALSE,FALSE,TRUE))
utworzenie nowej listy
lapply(x,mean)
Polecenie lapply stosuje zadaną funkcję (tutaj
mean) do każdego elementu listy
3.1 Zadania - Listy
3.1.1 Zadanie
Utworzyć 3-elementową listę zawierającą Twoje nazwisko, imiona
rodziców oraz miejsce urodzenia (fikcyjne, RODO itd). Nazwy elementów
listy to “nazwisko”, “imiona_rodzicow” i “miejsce_urodzenia”.
3.1.2 Zadanie
Utworzyć (ponownie) macierz
\(\mathbf{A}=\left( \begin{array}{ccc}
2&23&8\\10&6&90\\4&7&12\end{array}\right)\)
za pomocą poleceń cbind i/lub matrix.
Obliczyć wartości własne i wektory własne macierzy. Czy macierz
jest diagonalizowalna?
Na podstawie poprzedniego pytania obliczyć \(\mathbf{A}^n\) dla \(n=10\) oraz \(n=50\) nie używając pętli (algebra
liniowa…). Może się przydać polecenie inv z pakietu
matlib . Ładowanie za pomocą
library(matlib)
1 Macierze
Macierze, podobnie jak wektory, mogą zawierać elementy dowolnego, ale tego samego typu (nie można utworzyć macierzy zawierającej jednocześnie np. wartości liczbowych i tekstowych).
Podstawowa polecenie służące tworzeniu macierzy to
matrix(vec, nrow=n, ncol=p, byrow=T),
gdzie vec jest wektorem zawierającym kolejne elementy
macierzy, które standardowo będą rozmieszczone kolumnami. W celu
rozmieszczenia elementów wierszami należy wybrać opcję
byrow=T.
1.1 Tworzenie macierzy
1.2 Wybrane operacje na macierzach
Przetestować działanie poniższych poleceń
x3=t(x2) |
#Transpozycja macierzy x2 |
b=x1*x2 |
#Iloczyn macierzy element po elemencie |
b=x3%*%x2 |
#Standardowy iloczyn macierzy |
dim(b) |
#Podaje wymiar macierzy |
b[3,2] |
#Wybranie elementu b32 macierzy b |
b[3,2]=5 |
#Przypisanie wartości do elementu macierzy |
b[,2] |
#Wybranie drugiej kolumny macierzy b |
b[c(3,4),] |
#Wybranie wiersza 3 i 4 macierzy b |
b[-2,] |
#Wybranie wszystkich wierszy macierzy b poza drugim
wierszem |
b[,-c(2,4)] |
#Wybranie wszystkich kolumn macierzy b poza drugą i
czwartą |
b[1,]>600 |
# Wykonanie testu na pierwszym wierszu macierzy |
ind=which(b[1,]>600) |
|
b[,ind] |
#Wybranie tych kolumn macierzy b , których pierwszy
elementjest większy niż 600 (jako wynik wcześniejszego polecenia) |
rbind(x1,x2) |
#Połączenie wierszowe macierzy, czyli utworzenie macierzy, której wierszami są kolejne wiersze macierzy x1,a następnie macierzy x2. Polecenie to pozwala nadołączanie kolejnych wierszy do macierzy, efektem jest macierz postaci blokowej:\[ \left[ \begin{array}{c} x_1\\x_2 \end{array} \right] \] |
cbind(x1,x2) |
#Poziome, “kolumnowe” połączenie dwóch macierzy, czyli utworzenie
macierzy, w której (licząc od lewej) najpierw są kolumny macierzy
\[\left[ \begin{array}{c c} x_1 & x_2 \end{array} \right] \] |
apply(x1,2,sum) |
#Funkcja apply pozwala na zastosowanie funkcji
działającejna wektorach do macierzy x1 (w tym przypadku sumy)do kolumn (drugi argument jest tutaj równy 2) lub wierszy (drugi argument byłby równy 1). W wyniku dostajemy wektor zawierający sumy elementów poszczególnych kolumn macierzy x1 |
apply(x1,1,sum) |
#Jak wyżej, tylko tym razem otrzymujemy sumy elementów wierszami macierzy x1 |
apply(x1,1,max) |
#Otrzymujmy wektor zawierający element maksymalny każdego z wierszy macierzy x1 |
1.3 Zadania - macierze
1.3.1 Zadanie
Utworzyć wektor
x=(2;2;2;2;2)za pomocą funkcjireporaz wektory=(-1;0;1;2;3)za pomocą funkcjiseq.Utworzyć macierz A o 5 wierszach i 2 kolumnach, w której pierwsza kolumna składa się z elementów wektora
xa druga z elementów wektoray.Zmienić drugi wiersz macierzy A na wiersz postaci (2;4)
1.3.2 Zadanie
- Utworzyć macierz
\(\mathbf{A}=\left( \begin{array}{ccc} 2&23&8\\10&6&90\\4&7&12\end{array}\right)\)
za pomocą poleceńcbindi/lubmatrix. Czy da się utworzyć tą macierz za pomocą poleceniarbind? - Obliczyć średnią oraz iloczyn elementów w wierszach i kolumnach
macierzy A za pomocą funkcji
apply,sumorazprod. - Obliczyć sumę wszystkich liczb z dwóch pierwszych wierszy macierzy A, a następnie sumę wszystkich liczb z pierwszej i trzeciej kolumny
- Co zwracają polecenia
t(A),det(A)idiag(A)? Wyznaczyć ślad macierzy A. - Co zwracają polecenia
A^2,A*A,A%*%A? - Co zwracają polecenia
1/A,A^(-1),solve(A)? - Rozwiązać układ równań
\(\left\{ \begin{array}{ccc} 2x+23y+8z&=&5\\ 10x+6y+90z&=&6\\ 4x+7y+12z&=&7 \end{array} \right.\) - Wybrać te wiersze macierzy A, w których suma
elementów jest większa niż 30.
2 Ramki danych
Ramki danych (data.frame) są tablicami, których kolumny mogą być niejednorodne. Przykładowo, ramka może zawierać zarówno kolumny znakowe jak i numeryczne, ale każda kolumna zawiera elementy tego samego rodzaju. Jest to najważniejsza klasa obiektów dedykowana specjalnie do przechowywania danych.
Przykładowo, w ramce danych możemy umieścić zmienne jakościowe opisywane za pomocą znaków (np. kolumnę opisującą płeć M/K osoby lub jej status społeczno-zawodowy) oraz zmienne ilościowe opisywane za pomocą liczb (np. wzrost lub wiek). Wiele narzędzi statystycznych dostępnych w R jest dedykowanych tej klasie obiektów. Ramki danych tworzone są też zazwyczaj przez R podczas importu danych.
Ramki danych mogą być utworzone poprzez zgrupowanie wektorów
var1, var2,… o tej samej długości
poleceniem
data.frame(nazwa1=var1, nazwa2=var2,…)
Możliwe jest też przekształcenie macierzy w ramkę danych za pomocą
polecenia as.data.frame.
2.1 Tworzenie ramek danych i podstawowe operacje na ramkach
v1=sample(1:12,30,rep=T) |
#Losuje ze zbioru {1…12} ciąg 30 liczb z powtórzeniami |
v2=sample(LETTERS[1:10],30,rep=T) |
#Losuje ze zbioru liter {A,B,…J} ciąg 30 liter z powtórzeniami |
v3=runif(30) |
#30 niezależnych realizacji rozkładu jednostajnego na przedziale [0,1] |
hist(v3) |
#Rysuje histogram zmiennej v3 |
v4=rnorm(30) |
#30 niezależnych realizacji rozkładu normalnego o średniej 0 i wariancji 1 |
hist(v4) |
#Rysuje histogram zmiennej v4 |
xx=data.frame(Age=v1,Firstname=v2,Height=v3,Weight=v4) |
#Tworzy ramkę danych z 4 zmiennymi i 30 osobnikami/obserwacjami |
str(xx) |
#Wyświetla strukturę obiektu |
xx$Firstname |
#Do zmiennych możemy się odnosić poprzez $ i nazwę |
xx[,1] |
#Do zmiennych możemy się odnieść przez [ ], tak jak w
przypadku macierzy |
xx$Firstname[3] |
#Dostęp do trzeciego elementu wektora xx$Firstname |
xx[3,2] |
#To samo co wyżej |
summary(xx) |
#Podstawowe statystyki dla zmiennych |
str(xx) |
#Struktura obiektu może się różnić w zależności od występujących zmiennych ilościowych i jakościowych |
ma=matrix(1:15,nrow=3); ma |
#Tworzy nową macierz |
ma=as.data.frame(ma) |
#Zmienia macierz na ramkę danych |
ma |
#Wyświetlenie ramki |
str(ma) |
#Struktura ramki |
names(ma)=c('VA','VB','VC','VD','VE') |
#Przypisanie nazw zmiennym (kolumny ramki) |
row.names(ma)=c('l1','l2','l3') |
#Przypisanie nazw obserwacjom (wiersze ramki) |
ma |
#Wyświetlenie ramki |
2.2 Działania na zmiennych jakościowych (i ilościowych)
sex=sample(c('M','F'),100,rep=T) |
Wygenerowanie 100 realizacji zmiennej “sex” o wartościach “M” i “F” (mężczyzna, kobieta) |
height=rnorm(100,mean=170,sd=10) |
Wygenerowanie 100 realizacji zmiennej “height” z rozkładu normalnego o średniej “mean=170” i odchyleniu standardowym “sd=10” |
height[which(sex=='M')]=height[which(sex=='M')]+10 |
Dodanie do zmiennej “height” wartości 10, o ile zmiennej “sex” odpowiada wartość “M” - inaczej, mężczyźni statystycznie są wyżsi |
tapply(height,sex,mean) |
Obliczenie średniej zmiennej “height” osobno dla “M” i “F” |
tapply(height,sex,sd) |
Obliczenie odchylenia standardowego zmiennej “height” osobno dla “M” i “F” |
2.3 Gotowe zestawy danych
W R istnieją pewne gotowe zestawy danych, które można wykorzystać do ćwiczeń
data() |
Otwiera okno tekstowe z listą wszystkich tabel danych dostępnych w R |
women |
Wyświetla tabelę z danymi “women” |
? women |
Wyświetla opis ramki danych “women”. Dowiemy się, że wzrost jest w calach, a waga w funtach. |
names(women) |
Nazwy zmiennych w “women” |
attributes(women) |
Pewna charakterystyka “women”, w tym nazwy zmiennych, typ danych i nazwy obserwacji |
women$height |
Wyświetla wartości zmiennej “height” dla ramki
women |
apply(women,1,sum) |
Funkcję “apply” można stosować do ramek danych |
apply(women,2,max) |
Funkcję “apply” można stosować do ramek danych |
2.4 Zadania - Ramki danych
2.4.1 Zadanie
W ćwiczeniu wykorzystamy zbiór danych “iris” dostępny w R
Sprawdzić, czy jest to obiekt typu data.frame (ramka danych)
Co znajduje się w zbiorze danych?
Wpisz polecenie
summary(iris). Ile osobników gatunku versicolor znajduje się w tej bazie danych? Jaka jest średnia zmiennej Sepal.Width? Jaka jest najmniejsza wartość?Utwórz ramkę danych o nazwie “iris2”, który zawiera tylko osobniki gatunku “setosa”.
Posortuj osobniki gatunku “setosa” według długości działki kielicha (eng. sepal)
Znajdź średnie zmiennych Sepal.Length, Sepal.Width, Petal.Lehgth oraz Petal.Width przy użyciu funkcji
applyorazmean.Znajdź średnie zmiennej Sepal.Length dla każdego z trzech gatunków używając funkcji
tapplyorazmean.
2.4.2 Zadanie
Poniższa tabela przedstawia liczbę studentów przyjętych w pięciu miastach z podziałem na 5 typów kierunków: nauki humanistyczne, ścisłe, medyczne, sportowe i techniczne w 2006 roku:
| n. human. | n. ścisłe | medyczne | sportowe | techniczne | |
|---|---|---|---|---|---|
| Bordeaux | 12220 | 6596 | 7223 | 357 | 2239 |
| Lyon | 15310 | 6999 | 10921 | 395 | 3111 |
| Paryż | 112958 | 40244 | 46146 | 1247 | 7629 |
| Rennes | 8960 | 6170 | 4661 | 279 | 4013 |
| Tuluza | 12125 | 8233 | 6653 | 553 | 3178 |
Stworzyć ramkę danych zawierających dane z powyższej tabeli. W szczególności należy uzupełnić nazwy kolumn i wierszy jak wyżej (polecenia
namesirow.names)Obliczyć całkowita liczbę studentów w danym mieście, a następnie uporządkować tabelę w porządku rosnącym względem tej liczby
Obliczyć całkowita liczbę studentów danego typu kierunków, a następnie uporządkować tabelę w porządku rosnącym względem tej liczby
Utworzyć nowa ramkę danych zawierającą tylko te miasta, gdzie liczba przyjętych na kierunki ścisłe jest wyższa niż liczba przyjęć na kierunki medyczne (jedno polecenie/jedna linijka)
2.5 Zadanie - metoda D’Hondta podziału mandatów w systemach wyborczych
2.5.1 Wstęp
Weźmiemy pod uwage wyniki wyborów do Sejmu RP z 15 października 2023, dane dla okręgu nr 13 (Kraków i okolice) dostępne na stronie
W tym okręgu do obsadzenia jest 14 mandatów, próg wyborczy 5% przekroczyło 5 komitetów wyborczych i tylko te komitety bierzemy pod uwagę:
partie=c("KO","PiS", "3Droga","Lewica", "Konfederacja")
glosy =c(232799,232430,127693,83633,58435)
l_mandatow=14Gdyby zastosować wprost proporcjonalność zdobytych mandatów do liczby otrzymanych głosów dostalibyśmy wyniki ułamkowe:
#proporcjonalny podział głosów prowadzi do ułamkowych mandatów
razemglosy=sum(glosy)
udzial=glosy/razemglosy
ulamkowe_mandaty=l_mandatow*udzial
ulamkowe_mandaty## [1] 4.434327 4.427298 2.432281 1.593031 1.113063
i taki wynik byłby trudny do zinterpretowania.
2.5.2 Metoda D’Hondta
Metoda ta jest algorytmem umożliwiającym niejako rozparcelowanie ułamkowych mandatów między komitety wyborcze. Opis algorytmu można znaleźć na
W skrócie algorytm polega na zbudowaniu tabelki jak niżej, gdzie w pierwszym wierszu umieszczamy liczby głosów uzyskane przez poszczególne komitety, a następne wiersze powstają przez podzielenie (zawsze) pierwszego wiersza przez kolejne liczby naturalne. Ilość wierszy takiej tabelki odpowiada liczbie mandatów do rozdzielenia (istnieje możliwość, że ktoś zgarnie wszystkie mandaty).
Następnie z tabelki wybieramy najwyższe wyniki aż do wyczerpania liczby mandatów do obsadzenia w okręgu.
2.5.3 Zadanie właściwe - część pierwsza
Zbudować ramkę danych - tabelkę wyników z ilorazami wynikającymi z metody d’Hondta. Efekt powinien przypominać
## KO PiS 3Droga Lewica Konfederacja
## 1 232799.00 232430.00 127693.000 83633.000 58435.000
## 2 116399.50 116215.00 63846.500 41816.500 29217.500
## 3 77599.67 77476.67 42564.333 27877.667 19478.333
## 4 58199.75 58107.50 31923.250 20908.250 14608.750
## 5 46559.80 46486.00 25538.600 16726.600 11687.000
## 6 38799.83 38738.33 21282.167 13938.833 9739.167
## 7 33257.00 33204.29 18241.857 11947.571 8347.857
## 8 29099.88 29053.75 15961.625 10454.125 7304.375
## 9 25866.56 25825.56 14188.111 9292.556 6492.778
## 10 23279.90 23243.00 12769.300 8363.300 5843.500
## 11 21163.55 21130.00 11608.455 7603.000 5312.273
## 12 19399.92 19369.17 10641.083 6969.417 4869.583
## 13 17907.62 17879.23 9822.538 6433.308 4495.000
## 14 16628.50 16602.14 9120.929 5973.786 4173.929
W powyższej ramce nazwy kolumn to komitety wyborcze, a nazwy wierszy to kolejne dzielniki.
Wskazówki:
liczba głosów/wektor dzielników daje wektor ilorazów
wektory można połączyć w macierz za pomocą
cbindprzydatne:
as.data.frame,colnames,rownames
Z powyższej ramki danych należałoby wybrać 14 największych liczb (14, bo taka jest liczba mandatów w okręgu 13). Niestety, sortowanie macierzy jest nieco mało wygodne, w celu zautomatyzowania obliczeń zbudujemy inną, “lepszą” ramkę danych:
2.5.4 Zadanie właściwe - część druga
Ponieważ łatwiej posortować wektor, zbudujemy ramkę danych postaci:
## partia ilorazy
## 1 KO 232799.00
## 2 KO 116399.50
## 3 KO 77599.67
## 4 KO 58199.75
## 5 KO 46559.80
## 6 KO 38799.83
## partia ilorazy
## 65 Konfederacja 6492.778
## 66 Konfederacja 5843.500
## 67 Konfederacja 5312.273
## 68 Konfederacja 4869.583
## 69 Konfederacja 4495.000
## 70 Konfederacja 4173.929
gdzie pierwsza kolumna to kolejno sklonowane nazwy komitetów wyborczych (w liczbie równej liczbie mandatów), a druga kolumna to kolejne zestawy ilorazów.
Wskazówka: Ramkę tego typu możemy zbudować od
podstaw albo korzystając z ramki z pierwszej części i funkcji
stack().
Mając ramkę jak powyżej należy:
posortować malejąco kolumnę ilorazów (
order(), czy możesort()będzie lepszy?)wybrać pierwsze 14 wyników (odpowiadających liczbie mandatów)
wybrać nazwy komitetów odpowiadających 14 najlepszym wynikom/ilorazom
zliczyć liczbę mandatów za pomocą
table()
Powinniśmy dostać coś podobnego jak niżej, gdzie wyniki
table() zostały jeszcze raz posortowane
##
## KO PiS 3Droga Konfederacja Lewica
## 5 5 2 1 1
## [1] 4.434327 4.427298 2.432281 1.593031 1.113063
Mamy też porównanie z ułamkowymi mandatami, widzimy gdzie te ułamkowe części się poprzesuwały.
Można też sprawdzić, czy wyliczony przez nas podział zgadza się z oficjalnymi wynikami
2.5.5 Zadanie właściwe - część trzecia
Powtórzyć podział mandatów dla innego, wybranego okręgu i porównać z oficjalnymi wynikami.
2.5.6 Zadanie dodatkowe 1
Sprawdzić, jak wyglądałby podział mandatów, gdyby komitety zawarły koalicje, np. jakbyśmy zsumowali głosy KO+Lewica+3droga i PiS+Konfederacja.
2.5.7 Zadanie dodatkowe 2 - metoda Sainte-Laguë
Innym sposobem podziału mandatów jest wykorzystanie metody Sainte-Laguë. Różnica w stosunku do metody D’Hondta polega na tym, że dzielniki to kolejne liczby nieparzyste.
Więcej informacji na Wikipedia metoda Sainte-Laguë
Zadanie:
zmodyfikować kod tak, aby obliczał liczbę mandatów metodą Sainte-Laguë
porównać otrzymane wyniki z metody Sainte-Laguë oraz metody D’Hondta
Możliwe jest, że w niektórych okręgach liczby mandatów otrzymanych za pomocą obu metod będą różne (metoda D’Hondta bardziej sprzyja większym partiom)
2.5.8 Ciekawostka
W polskim systemie wyborczym, gdy znamy już liczbę mandatów przypadającą danemu komitetowi, bierzemy pod uwagę indywidualne wyniki kandydatów z danej listy.
Stąd też “układanki wyborcze”, tak aby znane nazwisko zdobyło nie tylko mandat dla siebie, ale znacznie poprawiło ogólny wynik listy, co daje większą liczbę mandatów.
3 Listy
Lista jest uporządkowanym zbiorem obiektów, nie koniecznie tego
samego typu. Elementami list mogą być dowolne obiekty zdefiniowane w R.
Można utworzyć na przykład listę, która zawiera wektor liczbowy i
macierz znaków. Własność ta jest wykorzystywana w szczególności przez
niektóre funkcje do zwracania złożonych wyników w formie pojedynczego
obiektu. Listę tworzy się za pomocą funkcji
list(nazwa1=el1, nazwa2=el2,…). Do każdego elementu listy
można przejść używając jego indeksu w nawiasach podwójnych
[[…]] lub jego nazwy poprzedzonej znakiem
$.
li=list(num=1:5,y="color",a=TRUE) |
utworzenie listy z 3 obiektami |
li |
wyświetlenie listy |
li$num |
dostęp do elementu listy przez $ |
li$a |
dostęp do elementu listy przez $ |
li[[1]] |
dostęp do elementu listy przez [[…]] |
li[[3]] |
dostęp do elementu listy przez [[…]] |
a=matrix(c(6,2,0,2,6,0,0,0,36),nrow=3) |
utworzenie macierzy |
eigen(a) |
obliczenie rozkładu Jordana macierzy |
res=eigen(a) |
Wynik podawany jest w postaci listy |
attributes(res) |
Pozwala na wyświetlenie nazw elementów listy |
str(res) |
Wyświetla strukturę listy |
res$values |
Wyświetlenie wartości własnych |
res$vectors |
Wyświetlenie wektorów własnych |
res$vectors[,1] |
Wyświetlenie pierwszego wektora własnego |
diag(res$values) |
Macierz Jordana (dokładniej macierz diagonalna, której elementy ma przekątnej pochodzą z wektora zawierającego wartości własne) |
res$vectors%*%diag(res$values)%*%t(res$vectors) |
Rozkład Jordana, macierz odwrotna = transponowana |
x<-list(a=1:10,beta=exp(-3:3),logic=c(TRUE,FALSE,FALSE,TRUE)) |
utworzenie nowej listy |
lapply(x,mean) |
Polecenie lapply stosuje zadaną funkcję (tutaj
mean) do każdego elementu listy |
3.1 Zadania - Listy
3.1.1 Zadanie
Utworzyć 3-elementową listę zawierającą Twoje nazwisko, imiona rodziców oraz miejsce urodzenia (fikcyjne, RODO itd). Nazwy elementów listy to “nazwisko”, “imiona_rodzicow” i “miejsce_urodzenia”.
3.1.2 Zadanie
Utworzyć (ponownie) macierz
\(\mathbf{A}=\left( \begin{array}{ccc} 2&23&8\\10&6&90\\4&7&12\end{array}\right)\)
za pomocą poleceńcbindi/lubmatrix.Obliczyć wartości własne i wektory własne macierzy. Czy macierz jest diagonalizowalna?
Na podstawie poprzedniego pytania obliczyć \(\mathbf{A}^n\) dla \(n=10\) oraz \(n=50\) nie używając pętli (algebra liniowa…). Może się przydać polecenie
invz pakietumatlib. Ładowanie za pomocąlibrary(matlib)