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
a=1:20
x1=matrix(a,nrow=5) #Tworzy macierz 5x4 z wektora `a` (wartości uporządkowane są kolumnami)
x1
x2=matrix(a,nrow=5,byrow=T) #Tworzy macierz 5x4
#z wektora `a` (wartości uporządkowane są wierszami)
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 1
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 2
- 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)?
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]
v4=rnorm(30)
#30 niezależnych realizacji rozkładu normalnego o średniej 0 i
wariancji 1
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
head(xx)
# Wyświetla 6 pierwszy wierszy ramki danych xx
tail(xx)
# Wyświetla 6 ostatnich wierszy ramki danych xx
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)
2.2 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.3 Zadania - ramki
danych
2.3.1 Zadanie 1
W analizie danych bardzo często wykorzystuje się ramki danych.
Dlatego też przetestujemy poznane operacje na zbiorze danych mieszkania
znajdującym się w bibliotece “Przewodnik”. Ponieważ te dane nie są
dostępne w podstawowej bibliotece, wymagana jest na początku jednorazowa
instalacja komendą install.packages("Przewodnik").
Następnie, wystarczy załadować bibliotekę
library("Przewodnik") oraz komendą
head(mieszkania) możemy wyświetlić 6 pierwszych rekordów,
aby zobaczyć co składa się na rozważany zbiór danych.
Wykonaj poniższe operacje na zbiorze danych “mieszkania”:
- Wypisz pierwszy, trzeci i piąty wiersz ramki danych.
- Wypisz pierwszy, trzeci i piąty wiersz oraz od 2 do 5 kolumny ramki
danych.
- Wpisz polecenie
summary(mieszkania). Jaka jest średnia
cena mieszkań? Jaka jest maksymalna powierzchnia mieszkania z naszym
zbiorze danych? Ile jest mieszkań znajdujących się w wieżowcach?
- Aby wypisać pierwszą kolumnę, jaką jest cena mieszkań możemy użyć:
mieszkania[,1] lub mieszkania$cena lub
mieszkania[, "cena"]. Znajdź jaka jest największa cena za
mieszkanie w rozważanym zbiorze danych, a następnie wyświetl wiersz
zawierający maksymalną cenę.
- Używając funkcji
order posortuj dane ze względu na
cenę.
- Swój nową ramkę danych która zawiera tylko cenę, powierzchnię i
dzielnicę mieszkań, które mają powierzchnię większą niż 20.
2.3.2 Zadanie 2
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). Dla ułatwienia,
macierz danych liczbowych można przekopiować z przykładu
macierz_miast=matrix(c(12220,15310,112958,8960,12125,6596,6999,40244,6170,8233,7223,10921,46146,4661,6653,357,395,1247,279,553,2239,3111,7629,4013,3178),ncol=5)
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.4 Zadanie - metoda
D’Hondta
2.4.1 Wstęp
Weźmiemy pod uwagę 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.4.2 Metoda D’Hondta -
opis
Metoda ta jest algorytmem umożliwiającym rozdzielenie 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 nieparzyste. Ilość wierszy
takiej tabelki odpowiada liczbie mandatów do rozdzielenia (istnieje
możliwość, że ktoś zgarnie wszystkie).
Następnie z tabelki wybieramy najwyższe wyniki aż do wyczerpania
liczby mandatów do obsadzenia w okręgu.
2.4.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.000 232430.000 127693.000 83633.000 58435.000
## 3 77599.667 77476.667 42564.333 27877.667 19478.333
## 5 46559.800 46486.000 25538.600 16726.600 11687.000
## 7 33257.000 33204.286 18241.857 11947.571 8347.857
## 9 25866.556 25825.556 14188.111 9292.556 6492.778
## 11 21163.545 21130.000 11608.455 7603.000 5312.273
## 13 17907.615 17879.231 9822.538 6433.308 4495.000
## 15 15519.933 15495.333 8512.867 5575.533 3895.667
## 17 13694.059 13672.353 7511.353 4919.588 3437.353
## 19 12252.579 12233.158 6720.684 4401.737 3075.526
## 21 11085.667 11068.095 6080.619 3982.524 2782.619
## 23 10121.696 10105.652 5551.870 3636.217 2540.652
## 25 9311.960 9297.200 5107.720 3345.320 2337.400
## 27 8622.185 8608.519 4729.370 3097.519 2164.259
W powyższej ramce nazwy kolumn to komitety wyborcze, a nazwy wierszy
to kolejne dzielniki.
Wskazówki
liczba głosów komitetu/wektor dzielników daje wektor ilorazów dla
danego komitetu
wektory można połączyć w macierz za pomocą cbind lub
bezpośrednio ramkę danych
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.4.4 Zadanie właściwe -
część druga
Ponieważ łatwiej posortować wektor, zbudujemy ramkę danych
postaci:
## partia ilorazy
## 1 KO 232799.00
## 2 KO 77599.67
## 3 KO 46559.80
## 4 KO 33257.00
## 5 KO 25866.56
## 6 KO 21163.55
## partia ilorazy
## 65 Konfederacja 3437.353
## 66 Konfederacja 3075.526
## 67 Konfederacja 2782.619
## 68 Konfederacja 2540.652
## 69 Konfederacja 2337.400
## 70 Konfederacja 2164.259
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.
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 Lewica Konfederacja
## 5 4 2 2 1
Mamy też porównanie z ułamkowymi mandatami:
## [1] 4.434327 4.427298 2.432281 1.593031 1.113063
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.4.5 Zadanie właściwe -
część trzecia
Powtórzyć podział mandatów dla innego, wybranego okręgu i porównać z
oficjalnymi wynikami.
2.4.6 Zadanie
dodatkowe
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.4.7 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.
2.5 Działania na
zmiennych jakościowych (i ilościowych)
Przypomnijmy, że do ramek danych możemy umieścić zmienne jakościowe
oraz zmienne ilościowe opisywane za pomocą liczb. Przyjrzymy się teraz
dokładniej tym pierwszym. Zmienne jakościowe reprezentują kategorie lub
grupy, które nie mają naturalnego porządku liczbowego. Przykładami mogą
być płeć (mężczyzna, kobieta), kolor (czerwony, zielony, niebieski) czy
odpowiedzi typu tak/nie.
sex=sample(c('M','F'),100,rep=T)
Wygenerowanie 100 realizacji zmiennej “sex” o wartościach “M” i “F”
(mężczyzna, kobieta)
table(sex)
Wyświetla tablice liczebności dla zmiennej “sex”
barplot(sex)
Graficzne przedstawienie liczebności dla zmiennej jakościowej
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”
Oczywiście, warto podkreślić, że stosowanie metod statystycznych
odpowiednich dla zmiennych ilościowych do analizy zmiennych jakościowych
może prowadzić do błędów lub bezsensownych wyników. Przykładem może być
próba obliczenia średniej dla zmiennej jakościowej.
## Warning in mean.default(kolory): argument is not numeric or logical: returning
## NA
## [1] NA
2.6 Zadania - zmienne
jakościowe
2.6.1 Zadanie 3
Kontynuując zadanie 1 (2.3.1) i wykorzystując zbiór danych
mieszkania:
Oblicz średnią cenę osobno dla każdej dzielnicy, używając funkcji
tapply oraz mean.
Wypisz wszystkie mieszkania dla których typ budynku to wieżowiec,
a następnie posortuj je ze względu na powierzchnię.
3 Listy
Lista jest uporządkowanym zbiorem obiektów, nie koniecznie tego
samego typu. Elementami list mogą być dowolne obiekty zdefiniowane w R,
którym można nadać nazwy. Na przykład, można utworzyć 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
$.
3.1 Wybrane operacje na
listach
li=list(num=1:5,y="color",a=TRUE)
utworzenie listy z 3 obiektami z nazwami elementów listy odpowiednio
num, y, a.
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 wartości własnych i wektorów 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
lapply(x,mean)
Polecenie lapply stosuje zadaną funkcję (tutaj
mean) do każdego elementu listy
3.2 Zadania - Listy
3.2.1 Zadanie 1
Utworzyć 5-elementową listę zawierającą dowolne dwa miasta, jedno
państwo, imię damskie i imię męskie, trzy zwierzęta oraz cyfrę, takie że
miasto, państwo, imię, zwierze zaczynają się na tą samą literę co twoje
imię a cyfra to suma cyfr twojego numeru indeksu. Nazwy elementów listy
to “miasto”, “państwo”, “imię”, “zwierze” oraz “cyfra”.
3.2.2 Zadanie 2
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?
3.2.3 Zadanie 3
Załaduj listę, która zawiera różne typy danych.
data_list <- list( numeryczny1 = c(10, 20, 30, 40, 50), numeryczny2 = c(10, 200, 34, 4, -50), kategoryczny = c("tak", "nie", "tak", "nie", "tak"), macierz = matrix(1:9, nrow=3))
Następnie, wykonaj następujące zadania:
Dla wektorów numerycznych oblicz medianę.
Dla zmiennych jakościowych oblicz liczbę wystąpień każdej
kategorii.
Dla macierzy oblicz sumę każdego wiersza i każdej
kolumny.
3.2.4 Zadanie 4
Dla poniższej listy
datalist <- list( zestaw1 = c(10, 20, 30, 40, 50), zestaw2 = c(5, 15, 25, 35, 45), zestaw3 = c(10, 10, 20, 20, 30))
używając funkcji lapply policz odchylenie standardowe oraz
średnią dla każdego elementu z listy.
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
a=1:20
x1=matrix(a,nrow=5) #Tworzy macierz 5x4 z wektora `a` (wartości uporządkowane są kolumnami)
x1
x2=matrix(a,nrow=5,byrow=T) #Tworzy macierz 5x4
#z wektora `a` (wartości uporządkowane są wierszami)
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 1
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 2
- 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)?
1.1 Tworzenie macierzy
a=1:20
x1=matrix(a,nrow=5) #Tworzy macierz 5x4 z wektora `a` (wartości uporządkowane są kolumnami)
x1
x2=matrix(a,nrow=5,byrow=T) #Tworzy macierz 5x4
#z wektora `a` (wartości uporządkowane są wierszami) 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 1
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 2
- 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)?
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]
v4=rnorm(30)
#30 niezależnych realizacji rozkładu normalnego o średniej 0 i
wariancji 1
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
head(xx)
# Wyświetla 6 pierwszy wierszy ramki danych xx
tail(xx)
# Wyświetla 6 ostatnich wierszy ramki danych xx
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)
2.2 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.3 Zadania - ramki
danych
2.3.1 Zadanie 1
W analizie danych bardzo często wykorzystuje się ramki danych.
Dlatego też przetestujemy poznane operacje na zbiorze danych mieszkania
znajdującym się w bibliotece “Przewodnik”. Ponieważ te dane nie są
dostępne w podstawowej bibliotece, wymagana jest na początku jednorazowa
instalacja komendą install.packages("Przewodnik").
Następnie, wystarczy załadować bibliotekę
library("Przewodnik") oraz komendą
head(mieszkania) możemy wyświetlić 6 pierwszych rekordów,
aby zobaczyć co składa się na rozważany zbiór danych.
Wykonaj poniższe operacje na zbiorze danych “mieszkania”:
- Wypisz pierwszy, trzeci i piąty wiersz ramki danych.
- Wypisz pierwszy, trzeci i piąty wiersz oraz od 2 do 5 kolumny ramki
danych.
- Wpisz polecenie
summary(mieszkania). Jaka jest średnia
cena mieszkań? Jaka jest maksymalna powierzchnia mieszkania z naszym
zbiorze danych? Ile jest mieszkań znajdujących się w wieżowcach?
- Aby wypisać pierwszą kolumnę, jaką jest cena mieszkań możemy użyć:
mieszkania[,1] lub mieszkania$cena lub
mieszkania[, "cena"]. Znajdź jaka jest największa cena za
mieszkanie w rozważanym zbiorze danych, a następnie wyświetl wiersz
zawierający maksymalną cenę.
- Używając funkcji
order posortuj dane ze względu na
cenę.
- Swój nową ramkę danych która zawiera tylko cenę, powierzchnię i
dzielnicę mieszkań, które mają powierzchnię większą niż 20.
2.3.2 Zadanie 2
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). Dla ułatwienia,
macierz danych liczbowych można przekopiować z przykładu
macierz_miast=matrix(c(12220,15310,112958,8960,12125,6596,6999,40244,6170,8233,7223,10921,46146,4661,6653,357,395,1247,279,553,2239,3111,7629,4013,3178),ncol=5)
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.4 Zadanie - metoda
D’Hondta
2.4.1 Wstęp
Weźmiemy pod uwagę 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.4.2 Metoda D’Hondta -
opis
Metoda ta jest algorytmem umożliwiającym rozdzielenie 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 nieparzyste. Ilość wierszy
takiej tabelki odpowiada liczbie mandatów do rozdzielenia (istnieje
możliwość, że ktoś zgarnie wszystkie).
Następnie z tabelki wybieramy najwyższe wyniki aż do wyczerpania
liczby mandatów do obsadzenia w okręgu.
2.4.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.000 232430.000 127693.000 83633.000 58435.000
## 3 77599.667 77476.667 42564.333 27877.667 19478.333
## 5 46559.800 46486.000 25538.600 16726.600 11687.000
## 7 33257.000 33204.286 18241.857 11947.571 8347.857
## 9 25866.556 25825.556 14188.111 9292.556 6492.778
## 11 21163.545 21130.000 11608.455 7603.000 5312.273
## 13 17907.615 17879.231 9822.538 6433.308 4495.000
## 15 15519.933 15495.333 8512.867 5575.533 3895.667
## 17 13694.059 13672.353 7511.353 4919.588 3437.353
## 19 12252.579 12233.158 6720.684 4401.737 3075.526
## 21 11085.667 11068.095 6080.619 3982.524 2782.619
## 23 10121.696 10105.652 5551.870 3636.217 2540.652
## 25 9311.960 9297.200 5107.720 3345.320 2337.400
## 27 8622.185 8608.519 4729.370 3097.519 2164.259
W powyższej ramce nazwy kolumn to komitety wyborcze, a nazwy wierszy
to kolejne dzielniki.
Wskazówki
liczba głosów komitetu/wektor dzielników daje wektor ilorazów dla
danego komitetu
wektory można połączyć w macierz za pomocą cbind lub
bezpośrednio ramkę danych
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.4.4 Zadanie właściwe -
część druga
Ponieważ łatwiej posortować wektor, zbudujemy ramkę danych
postaci:
## partia ilorazy
## 1 KO 232799.00
## 2 KO 77599.67
## 3 KO 46559.80
## 4 KO 33257.00
## 5 KO 25866.56
## 6 KO 21163.55
## partia ilorazy
## 65 Konfederacja 3437.353
## 66 Konfederacja 3075.526
## 67 Konfederacja 2782.619
## 68 Konfederacja 2540.652
## 69 Konfederacja 2337.400
## 70 Konfederacja 2164.259
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.
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 Lewica Konfederacja
## 5 4 2 2 1
Mamy też porównanie z ułamkowymi mandatami:
## [1] 4.434327 4.427298 2.432281 1.593031 1.113063
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.4.5 Zadanie właściwe -
część trzecia
Powtórzyć podział mandatów dla innego, wybranego okręgu i porównać z
oficjalnymi wynikami.
2.4.6 Zadanie
dodatkowe
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.4.7 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.
2.5 Działania na
zmiennych jakościowych (i ilościowych)
Przypomnijmy, że do ramek danych możemy umieścić zmienne jakościowe
oraz zmienne ilościowe opisywane za pomocą liczb. Przyjrzymy się teraz
dokładniej tym pierwszym. Zmienne jakościowe reprezentują kategorie lub
grupy, które nie mają naturalnego porządku liczbowego. Przykładami mogą
być płeć (mężczyzna, kobieta), kolor (czerwony, zielony, niebieski) czy
odpowiedzi typu tak/nie.
sex=sample(c('M','F'),100,rep=T)
Wygenerowanie 100 realizacji zmiennej “sex” o wartościach “M” i “F”
(mężczyzna, kobieta)
table(sex)
Wyświetla tablice liczebności dla zmiennej “sex”
barplot(sex)
Graficzne przedstawienie liczebności dla zmiennej jakościowej
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”
Oczywiście, warto podkreślić, że stosowanie metod statystycznych
odpowiednich dla zmiennych ilościowych do analizy zmiennych jakościowych
może prowadzić do błędów lub bezsensownych wyników. Przykładem może być
próba obliczenia średniej dla zmiennej jakościowej.
## Warning in mean.default(kolory): argument is not numeric or logical: returning
## NA
## [1] NA
2.6 Zadania - zmienne
jakościowe
2.6.1 Zadanie 3
Kontynuując zadanie 1 (2.3.1) i wykorzystując zbiór danych
mieszkania:
Oblicz średnią cenę osobno dla każdej dzielnicy, używając funkcji
tapply oraz mean.
Wypisz wszystkie mieszkania dla których typ budynku to wieżowiec,
a następnie posortuj je ze względu na powierzchnię.
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] |
v4=rnorm(30) |
#30 niezależnych realizacji rozkładu normalnego o średniej 0 i wariancji 1 |
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 |
head(xx) |
# Wyświetla 6 pierwszy wierszy ramki danych xx |
tail(xx) |
# Wyświetla 6 ostatnich wierszy ramki danych xx |
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) |
2.2 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.3 Zadania - ramki danych
2.3.1 Zadanie 1
W analizie danych bardzo często wykorzystuje się ramki danych.
Dlatego też przetestujemy poznane operacje na zbiorze danych mieszkania
znajdującym się w bibliotece “Przewodnik”. Ponieważ te dane nie są
dostępne w podstawowej bibliotece, wymagana jest na początku jednorazowa
instalacja komendą install.packages("Przewodnik").
Następnie, wystarczy załadować bibliotekę
library("Przewodnik") oraz komendą
head(mieszkania) możemy wyświetlić 6 pierwszych rekordów,
aby zobaczyć co składa się na rozważany zbiór danych.
Wykonaj poniższe operacje na zbiorze danych “mieszkania”:
- Wypisz pierwszy, trzeci i piąty wiersz ramki danych.
- Wypisz pierwszy, trzeci i piąty wiersz oraz od 2 do 5 kolumny ramki danych.
- Wpisz polecenie
summary(mieszkania). Jaka jest średnia cena mieszkań? Jaka jest maksymalna powierzchnia mieszkania z naszym zbiorze danych? Ile jest mieszkań znajdujących się w wieżowcach? - Aby wypisać pierwszą kolumnę, jaką jest cena mieszkań możemy użyć:
mieszkania[,1]lubmieszkania$cenalubmieszkania[, "cena"]. Znajdź jaka jest największa cena za mieszkanie w rozważanym zbiorze danych, a następnie wyświetl wiersz zawierający maksymalną cenę. - Używając funkcji
orderposortuj dane ze względu na cenę. - Swój nową ramkę danych która zawiera tylko cenę, powierzchnię i dzielnicę mieszkań, które mają powierzchnię większą niż 20.
2.3.2 Zadanie 2
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). Dla ułatwienia, macierz danych liczbowych można przekopiować z przykładu
macierz_miast=matrix(c(12220,15310,112958,8960,12125,6596,6999,40244,6170,8233,7223,10921,46146,4661,6653,357,395,1247,279,553,2239,3111,7629,4013,3178),ncol=5)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.4 Zadanie - metoda D’Hondta
2.4.1 Wstęp
Weźmiemy pod uwagę 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.4.2 Metoda D’Hondta - opis
Metoda ta jest algorytmem umożliwiającym rozdzielenie 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 nieparzyste. Ilość wierszy takiej tabelki odpowiada liczbie mandatów do rozdzielenia (istnieje możliwość, że ktoś zgarnie wszystkie).
Następnie z tabelki wybieramy najwyższe wyniki aż do wyczerpania liczby mandatów do obsadzenia w okręgu.
2.4.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.000 232430.000 127693.000 83633.000 58435.000
## 3 77599.667 77476.667 42564.333 27877.667 19478.333
## 5 46559.800 46486.000 25538.600 16726.600 11687.000
## 7 33257.000 33204.286 18241.857 11947.571 8347.857
## 9 25866.556 25825.556 14188.111 9292.556 6492.778
## 11 21163.545 21130.000 11608.455 7603.000 5312.273
## 13 17907.615 17879.231 9822.538 6433.308 4495.000
## 15 15519.933 15495.333 8512.867 5575.533 3895.667
## 17 13694.059 13672.353 7511.353 4919.588 3437.353
## 19 12252.579 12233.158 6720.684 4401.737 3075.526
## 21 11085.667 11068.095 6080.619 3982.524 2782.619
## 23 10121.696 10105.652 5551.870 3636.217 2540.652
## 25 9311.960 9297.200 5107.720 3345.320 2337.400
## 27 8622.185 8608.519 4729.370 3097.519 2164.259
W powyższej ramce nazwy kolumn to komitety wyborcze, a nazwy wierszy to kolejne dzielniki.
Wskazówki
liczba głosów komitetu/wektor dzielników daje wektor ilorazów dla danego komitetu
wektory można połączyć w macierz za pomocą
cbindlub bezpośrednio ramkę danychprzydatne:
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.4.4 Zadanie właściwe - część druga
Ponieważ łatwiej posortować wektor, zbudujemy ramkę danych postaci:
## partia ilorazy
## 1 KO 232799.00
## 2 KO 77599.67
## 3 KO 46559.80
## 4 KO 33257.00
## 5 KO 25866.56
## 6 KO 21163.55
## partia ilorazy
## 65 Konfederacja 3437.353
## 66 Konfederacja 3075.526
## 67 Konfederacja 2782.619
## 68 Konfederacja 2540.652
## 69 Konfederacja 2337.400
## 70 Konfederacja 2164.259
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.
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 Lewica Konfederacja
## 5 4 2 2 1
Mamy też porównanie z ułamkowymi mandatami:
## [1] 4.434327 4.427298 2.432281 1.593031 1.113063
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.4.5 Zadanie właściwe - część trzecia
Powtórzyć podział mandatów dla innego, wybranego okręgu i porównać z oficjalnymi wynikami.
2.4.6 Zadanie dodatkowe
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.4.7 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.
2.5 Działania na zmiennych jakościowych (i ilościowych)
Przypomnijmy, że do ramek danych możemy umieścić zmienne jakościowe oraz zmienne ilościowe opisywane za pomocą liczb. Przyjrzymy się teraz dokładniej tym pierwszym. Zmienne jakościowe reprezentują kategorie lub grupy, które nie mają naturalnego porządku liczbowego. Przykładami mogą być płeć (mężczyzna, kobieta), kolor (czerwony, zielony, niebieski) czy odpowiedzi typu tak/nie.
sex=sample(c('M','F'),100,rep=T) |
Wygenerowanie 100 realizacji zmiennej “sex” o wartościach “M” i “F” (mężczyzna, kobieta) |
table(sex) |
Wyświetla tablice liczebności dla zmiennej “sex” |
barplot(sex) |
Graficzne przedstawienie liczebności dla zmiennej jakościowej |
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” |
Oczywiście, warto podkreślić, że stosowanie metod statystycznych odpowiednich dla zmiennych ilościowych do analizy zmiennych jakościowych może prowadzić do błędów lub bezsensownych wyników. Przykładem może być próba obliczenia średniej dla zmiennej jakościowej.
## Warning in mean.default(kolory): argument is not numeric or logical: returning
## NA
## [1] NA
2.6 Zadania - zmienne jakościowe
2.6.1 Zadanie 3
Kontynuując zadanie 1 (2.3.1) i wykorzystując zbiór danych mieszkania:
Oblicz średnią cenę osobno dla każdej dzielnicy, używając funkcji
tapplyorazmean.Wypisz wszystkie mieszkania dla których typ budynku to wieżowiec, a następnie posortuj je ze względu na powierzchnię.
3 Listy
Lista jest uporządkowanym zbiorem obiektów, nie koniecznie tego
samego typu. Elementami list mogą być dowolne obiekty zdefiniowane w R,
którym można nadać nazwy. Na przykład, można utworzyć 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
$.
3.1 Wybrane operacje na listach
li=list(num=1:5,y="color",a=TRUE) |
utworzenie listy z 3 obiektami z nazwami elementów listy odpowiednio
num, y, a. |
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 wartości własnych i wektorów 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 |
lapply(x,mean) |
Polecenie lapply stosuje zadaną funkcję (tutaj
mean) do każdego elementu listy |
3.2 Zadania - Listy
3.2.1 Zadanie 1
Utworzyć 5-elementową listę zawierającą dowolne dwa miasta, jedno państwo, imię damskie i imię męskie, trzy zwierzęta oraz cyfrę, takie że miasto, państwo, imię, zwierze zaczynają się na tą samą literę co twoje imię a cyfra to suma cyfr twojego numeru indeksu. Nazwy elementów listy to “miasto”, “państwo”, “imię”, “zwierze” oraz “cyfra”.
3.2.2 Zadanie 2
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?
3.2.3 Zadanie 3
Załaduj listę, która zawiera różne typy danych.
data_list <- list( numeryczny1 = c(10, 20, 30, 40, 50), numeryczny2 = c(10, 200, 34, 4, -50), kategoryczny = c("tak", "nie", "tak", "nie", "tak"), macierz = matrix(1:9, nrow=3))
Następnie, wykonaj następujące zadania:
Dla wektorów numerycznych oblicz medianę.
Dla zmiennych jakościowych oblicz liczbę wystąpień każdej kategorii.
Dla macierzy oblicz sumę każdego wiersza i każdej kolumny.
3.2.4 Zadanie 4
Dla poniższej listy
datalist <- list( zestaw1 = c(10, 20, 30, 40, 50), zestaw2 = c(5, 15, 25, 35, 45), zestaw3 = c(10, 10, 20, 20, 30))
używając funkcji lapply policz odchylenie standardowe oraz
średnią dla każdego elementu z listy.