1 Početni koraci
U ovom poglavlju proći ćemo kroz osnovne strukture podataka u R-u.
Pored ovoga, dobar pregled nekih osnovnih stvari koje se mogu raditi u R-u se može videti u materijalima koleginice Tamare Milić.
1.1 Primitivni tipovi
1.1.1 Logicki tip - logical
(true/false)
## [1] TRUE
## [1] FALSE
Pisu se velikim slovima, 2 vrednosti - TRUE, FALSE
Kao uvek, 0 je FALSE
## [1] TRUE
Postoje operatori kao u drugim jezicima !
, &&
, ||
## [1] FALSE
1.1.2 Brojevi - numeric
(interno uvek double)
## [1] 11
## [1] 1.5
sa celobrojnim deljenjem
## [1] "numeric"
1.1.3 Celi brojevi - integer
(interno int (mozda long)):
## [1] 5
## [1] "integer"
## [1] 1.666667
zelimo celobrojno deljenje
operator celobrojnog deljenja je
## [1] 1
mozemo i da promenimo klasu broja u integer
## [1] 1
Operacije nad brojevima koje su moguce su:
+, -, *, /, %/%, %%, ^
## [1] 4
## [1] 1024
sve je slicno matlabu
postoje ugradjene funkcije exp, sin, cos, tan, atan, asin, itd.
## [1] 1.224647e-16
rezultat ovoga nije bas nula, vec 1.22e-16 = 1.22 * 10^(-16)
standardna prica sa poredjenjem double/float vrednosti stoji
## [1] FALSE
## [1] TRUE
1.1.4 Stringovi - character
(ne postoji razlika izmedju stringa i karaktera, sve su stringovi)
## [1] "character"
1.1.4.1 Neke korisne funkcije za stringove
spajanje:
## [1] "a b"
## [1] "ab"
## [1] "Ja <3 matf"
## [1] "1 < 2 < 3"
c stil formatiranja
## [1] "Broj 7. Izvucen je broj 8."
## [1] "Broj 3.14."
1.1.4.2 glue - korisna biblioteka za rad sa stringovima stringova
# install.packages("glue") # ovako se instaliraju paketi.
library(glue) # ovako se ucitavaju paketi
glue("{who} <3 {what}", who = "Ja", what = "fon")
## Ja <3 fon
## 17 == 17
istrazite sami paket, premocan je
1.2 Vektori
vektori se prave sa funkcijom c
(c = combine)
## [1] 1 2 3
precica za vektore ovog tipa:
## [1] 1 2 3
## [1] 1 3 45 65
sve operacije nad brojevima mogu se primeniti i na vektore i primenjuju se
element po element. Ako znate matlab, razlika je sto su u R sve operacije nad
vektorima rade element po element, a za matricno mnozenje i slicno se koriste
posebni operatori. Znaci a * b u R je isto kao a .* b u MATLAB
## [1] 4 6
## [1] 11 24 39 56 75 96 119 144 171 200
## [1] 12 14 16 18 20 22 24 26 28 30
## [1] 1.000000e+00 4.096000e+03 1.594323e+06 2.684355e+08 3.051758e+10
## [6] 2.821110e+12 2.326305e+14 1.801440e+16 1.350852e+18 1.000000e+20
Nad vektorima postoje razne funkcije poput sum, mean, var, sd, median, itd., a
i sve elementarne funkcije koje postoje nad brojevima su vektorizovane za
vektore, pa je npr. sin(c(1, 2)) = c(sin(1), sin(2))
## [1] 0.8414710 0.9092974 0.1411200 -0.7568025 -0.9589243 -0.2794155
## [7] 0.6569866 0.9893582 0.4121185 -0.5440211
vektori mogu sadrzati elemente samo jednog primitivnog tipa
## [1] 1 2
## [1] 1 2
## [1] "a" "b"
## [1] "a" "2"
## [1] TRUE FALSE
Ukoliko se tipovi ne slazu, pretvorice se u najfleksibilniji tip, znaci
logical -> integer -> numeric -> character
## [1] "character"
I logicki operatori su vektorizovani, pa je
## [1] TRUE FALSE FALSE FALSE TRUE
postoje funkcije any, all kao u MATLAB-u
## [1] TRUE
## [1] FALSE
Kad su logicki vektori u pitanju obratiti paznju na & i &&, kao i | i ||
R INFERNO and and andand
& i | rade vektorski - element po element i vracaju vektor!
## [1] FALSE FALSE TRUE FALSE
## [1] TRUE TRUE TRUE FALSE
&& i || porede samo prve elemente
## [1] FALSE
## [1] TRUE
1.3 Matrice
matrice se prave funckijom matrix
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
## [3,] 3 6 9
prvi argument oznacava elemente koje ce sadrzati, to je jedan vektor, pri cemu
se u matricu upisuju po kolonama, ukoliko nije specificirano drugacije. nrow
argument (ili ncol) specifikuju koliko vrsta ima matrica.
## [,1] [,2] [,3]
## [1,] 1 2 3
## [2,] 1 2 3
## [3,] 1 2 3
za lepsi zapis moze se koristiti byrow = TRUE i pisati ovako
## [,1] [,2] [,3]
## [1,] 1 1 1
## [2,] 2 2 2
## [3,] 3 3 3
Sve elementarne funkcije nad matricama rade kao nad vektorima, znaci vracaju
matricu, a primenjuju funkciju na svaki element.
Mnozenje matrica se radi operatorom %*%, transponovanje funkcijom t()
## [,1] [,2] [,3]
## [1,] 1 2 3
## [2,] 1 2 3
## [3,] 1 2 3
## [,1] [,2] [,3]
## [1,] 6 6 6
## [2,] 12 12 12
## [3,] 18 18 18
Skalarno mnozenje se moze implementirati na vise nacina, npr
## [1] 32
ili mnozenjem uTv
## [,1]
## [1,] 32
Primetimo da poslednji izraz vraca 1x1 matricu, a prvi vraca broj, tj vektor
velicine 1. Sa as.numeric mozemo to srediti.
## [1] 32
Vektori kad se tumace kao matrice su naravno kolone vektori.
1.4 Liste
Liste su nizovi koji mogu da sadrze objekte razlicitih tipova. Prakticno mogu da sadrze kao svoje elemente bilo koji objekat u R-u: vektore, matrice, druge liste, itd.
n <- c(2, 3, 5)
s <- c("aa", "bb", "cc", "dd", "ee")
b <- c(TRUE, FALSE, TRUE, FALSE, FALSE)
lst <- list(n, s, b) # lst sadrzi kopije od n, s, b
## [[1]]
## [1] 2 3 5
## [[1]]
## [1] "aa" "bb" "cc" "dd" "ee"
Na ovaj način dobijamo kopije prvog, odnosno drugog člana liste
Međutim ako hoćemo da direktno pristupimo članu liste koristimo [[ ]]
## [1] 2 3 5
Tada možemo da menjamo sadržaj liste
Liste mogu imati i imena clanova, kojima se onda moze pristupati dolarima $
.
## [1] 1 2 3 4 5
## [1] 1 2 3 4 5
1.5 Dataframe
Dataframe je najčešći način čuvanja podataka u R-u i vrlo je pogodan za rad i analizu. Služi za prikaz tabelarnih podataka, pa liči na matricu, s tim što je dataframe u snovi lista koja sadrži vektore jednakih dužina (kolone), pri čemu ti vektori ne moraju biti istog tipa. Dakle možemo imati jednu kolonu koju čine brojevi, a drugu tekstualni podaci.
Dataframe se pravi na sledeći način:
## kolona1 kolona2
## 1 1 prvi
## 2 2 drugi
## 3 3 treci
Ovako smo dobili dataframe sa dve kolone, od kojih je jedna numerička a druga tekstualna.
## 'data.frame': 3 obs. of 2 variables:
## $ kolona1: num 1 2 3
## $ kolona2: Factor w/ 3 levels "drugi","prvi",..: 2 1 3
R podrazumevano pretvara tekstualne podatke u faktore, to možemo preduprediti ako dodamo argument stringsAsFactors = FALSE
.
df <- data.frame(kolona1 = c(1, 2, 3), kolona2 = c("prvi", "drugi", "treci"), stringsAsFactors = FALSE)
str(df)
## 'data.frame': 3 obs. of 2 variables:
## $ kolona1: num 1 2 3
## $ kolona2: chr "prvi" "drugi" "treci"
## kolona1 kolona2
## 1 1 prvi
## 2 2 drugi
## 3 3 treci
Dva dataframe-a (koji imaju isi broj vrsta) se mogu spojiti da dobijemo više kolona korišćenjem funkcije cbind
.
df1 <- data.frame(kolona1 = c(1, 2, 3), kolona2 = c("prvi", "drugi", "treci"), stringsAsFactors = FALSE)
df2 <- data.frame(kolona3 = c(4,5,6), kolona4 = c("prvi1", "drugi1", "treci1"), stringsAsFactors = FALSE)
df3 <- cbind(df1, df2)
df3
## kolona1 kolona2 kolona3 kolona4
## 1 1 prvi 4 prvi1
## 2 2 drugi 5 drugi1
## 3 3 treci 6 treci1
Takodje, mogu se nadovezati po vrstama (ako imaju ista imena kolona) funkcijom rbind
.
df1 <- data.frame(kolona1 = c(1, 2, 3), kolona2 = c("prvi", "drugi", "treci"), stringsAsFactors = FALSE)
df2 <- data.frame(kolona1 = c(4,5,6), kolona2 = c("prvi1", "drugi1", "treci1"), stringsAsFactors = FALSE)
df4 <- rbind(df1, df2)
df4
## kolona1 kolona2
## 1 1 prvi
## 2 2 drugi
## 3 3 treci
## 4 4 prvi1
## 5 5 drugi1
## 6 6 treci1
Vrednostima kolona možemo pristupati pomoću operatora $
, kao u listama, a istim možemo i dodati nove kolone.
## [1] 1 2 3
## kolona1 kolona2 kolona5
## 1 1 prvi 7
## 2 2 drugi 8
## 3 3 treci 9
Medjutim, možda elegantniji način filtriranja i odabira podskupova dataframe-a je korišćenjem uglatih zagrada. Koristimo notaciju df[redovi, kolone]
, gde prvim argumentom odredjujemo koje redove želimo da uzmemo, a drugim koje kolone. Prazno mesto za neki od argumenata znači “uzmi sve”.
## kolona1 kolona2 kolona5
## 1 1 prvi 7
## 2 2 drugi 8
## 3 3 treci 9
## kolona1 kolona2 kolona5
## 1 1 prvi 7
## [1] 1 2 3
Redovi mogu biti ili vektori brojeva koji označavaju indekse redova koje da uzmemo, ili vektori TRUE/FALSE vrednosti iste dužine kao broj vrsta u dataframe-u, pri čemu se tada biraju redovi na pozicijama gde je u vektoru vrednost TRUE.
## kolona1 kolona2
## 1 1 prvi
## 3 3 treci
## 4 4 prvi1
## kolona1 kolona2
## 4 4 prvi1
## 5 5 drugi1
## 6 6 treci1
Kolone mogu biti ili vektori brojeva koji označavaju koje kolone da uzmemo prema indeksu, ili vektori stringova, koji označavaju imena kolona koje da uzmemo.
## kolona1 kolona3
## 1 1 4
## 2 2 5
## 3 3 6
## kolona1 kolona3
## 1 1 4
## 2 2 5
## 3 3 6
## kolona1 kolona3
## 1 1 4
## 3 3 6
Korisna stvar je da ako koristimo vektore brojeva za indeksiranje, ukoliko stavimo znak -
ispred, to znači da izuzimamo te redove/kolone.
## kolona2 kolona5
## 1 prvi 7
## 2 drugi 8
## 3 treci 9
## kolona1 kolona2 kolona5
## 1 1 prvi 7
## 3 3 treci 9
## kolona2 kolona5
## 3 treci 9
Konačno, za osnovne informacije o tabeli postoje funkcije colnames
, rownames
, ncol
i nrow
, za koje možete pretpostaviti šta rade.