Prije nego počnemo sa radom, potrebno je da učitamo prethnodno instalirane R pakete koji će nam biti potrebni za rad sa datotekama:
rm(list = ls()) # funkcija kojom čistimo radnu površinu
library('foreign') # Paket "foreign" čemo koristit za učitavanje baza kreiranih u drugim statističkim programima
library('car') # Paket "car" ćemo koristiti za rekodiranje varijabli
Na prethodnim časovima pokrili smo osnovne načine kako unijeti i izbaciti podatke iz R-a, kao i kako ispitati što se u našim podacima nalazi. Nakon što imamo jasnu sliku o podacima, možemo početi raditi s njima.
Nedostajući podaci u R označavaju se kao NA (nemojte ih miješati s NaN, što znači „nije broj - not a number“ - to se obično pojavljuje kada pokušate napraviti računsku operaciju koji nijeste trebali, na primjer ako 0 podijelite sa 0). Međutim, obje se smatraju vrijednostima koje nedostaju ako pitate R o njima. To možete učiniti s funkcijom is.na()
.
na <- c(4, NA, 8, 5, NaN)
is.na(na)
[1] FALSE TRUE FALSE FALSE TRUE
Nedostajući podaci mogu predstavljati problem, jer nekompletne datoteke onemogućuju određene proračune u procjeni statističkih modela. U mnogim slučajevima se podaci koji nedostaju automatski su isključeni, tako da o tome ne morate previše brinuti. Međutim, i dalje biste trebali biti svjesni količine podataka koji nedostaju u vašoj datoteci, jer je to ključni pokazatelj kvaliteta podataka, ali i kvalitete vaših proračuna. Ako transformišete varijable, prećerana količina podataka koji nedostaju može biti znak da radite nešto pogrešno. Osim toga, postoje neke funkcije koje su vrlo ośetljive kad su u pitanju nedostajući podaci i mogu rezultirati greškom ako R-u ne kažete aočno što s njima da radi.
Upotrijebimo niz podataka o kvalitetu vazduha kako bismo višeli koji podaci nedostaju, jer ih ima prilično. To je skup mjerenja kvaliteta vazduha u New Yorku iz 1973. godine.
data(airquality)
head(airquality)
Ozone Solar.R Wind Temp Month Day
1 41 190 7.4 67 5 1
2 36 118 8.0 72 5 2
3 12 149 12.6 74 5 3
4 18 313 11.5 62 5 4
5 NA NA 14.3 56 5 5
6 28 NA 14.9 66 5 6
Neke podatke koji nedostaju već možemo višeti ako pogledamo početak datoteke s podacima. Ako sumiramo podatke, možemo viđeti broj vrijednosti koje nedostaju u svim varijablama.
summary(airquality)
Ozone Solar.R Wind Temp
Min. : 1.00 Min. : 7.0 Min. : 1.700 Min. :56.00
1st Qu.: 18.00 1st Qu.:115.8 1st Qu.: 7.400 1st Qu.:72.00
Median : 31.50 Median :205.0 Median : 9.700 Median :79.00
Mean : 42.13 Mean :185.9 Mean : 9.958 Mean :77.88
3rd Qu.: 63.25 3rd Qu.:258.8 3rd Qu.:11.500 3rd Qu.:85.00
Max. :168.00 Max. :334.0 Max. :20.700 Max. :97.00
NA's :37 NA's :7
Month Day
Min. :5.000 Min. : 1.0
1st Qu.:6.000 1st Qu.: 8.0
Median :7.000 Median :16.0
Mean :6.993 Mean :15.8
3rd Qu.:8.000 3rd Qu.:23.0
Max. :9.000 Max. :31.0
Varijable Ozon i Solar.R imaju brojne vrijednosti koje nedostaju. Ali kako izgleda skup podataka u cjelini? Koliko ima cjelovitih slučajeva svih varijabli? Ideju o tome možemo dobiti upotrebom funkcije complete.cases()
. Ovo vraća logičku vrijednost za svaki redak u skupu podataka, to je TRUE
kada u redu nema podataka i FALSE
ako podatak postoji.
complete.cases(airquality)
[1] TRUE TRUE TRUE TRUE FALSE FALSE TRUE TRUE TRUE FALSE FALSE TRUE
[13] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[25] FALSE FALSE FALSE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE
[37] FALSE TRUE FALSE TRUE TRUE FALSE FALSE TRUE FALSE FALSE TRUE TRUE
[49] TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[61] FALSE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
[73] TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE
[85] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
[97] FALSE FALSE TRUE TRUE TRUE FALSE FALSE TRUE TRUE TRUE FALSE TRUE
[109] TRUE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE FALSE TRUE
[121] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[133] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[145] TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE
Ako želimo znati koliko je cjelovitih i nepotpunih slučajeva, možemo tražiti od R da zbir ovog vektora logičkih vrijednosti - śetimo se da je TRUE
1, a FALSE
0. Da bismo prebrojali kompletne slučajeve, možemo samo tražiti zbir, da prebrojimo nepotpune slučajeve, vrijednosti vektora možemo preokrenuti koristeći !
operater.
sum(complete.cases(airquality))/nrow(airquality) # This is for complete cases
[1] 0.7254902
Ovo možemo koristiti za čišćenje baze podataka od vrijednosti koje nedostaju, ako odaberemo samo redove koji sadrže cjelovite slučajeve.
airquality_clean1 <- airquality[complete.cases(airquality),]
dim(airquality_clean1)
[1] 111 6
Pogledajmo sada neke primjere, đe nedostajući podaci predstavljaju problem za neke proračune. Ako zamolimo R da nam da zbir, srednju vrijednost ili standardnu devijaciju varijable, a nedostaju podaci, dobit ćemo vrijednost koja nedostaje iako to nije ono što želimo.
mean(airquality$Ozone)
[1] NA
sum(airquality$Ozone)
[1] NA
sd(airquality$Ozone)
[1] NA
U takvim slučajevima ne moramo nužno ukloniti slučajeve s podacima koji nedostaju iz objekta podataka, samo moramo reći R-u da to automatski učini. To se radi argumentom na.rm
, koji poprima logičke vrijednosti TRUE
i FALSE
.
mean(airquality$Ozone, na.rm=TRUE)
[1] 42.12931
Za neke funkcije, koje koriste mnoge varijable, moramo R-u dati naredbu da automatski koristi kompletne slučajeve. To vrijedi i za funkciju cor ()
koja nam daje korelaciju između dvije varijable. Ovđe vrijednost "complete.obs"
govori R-u da za obračun koristi samo kompletne slučajeve.
cor(airquality$Ozone, airquality$Solar.R)
[1] NA
cor(airquality$Ozone, airquality$Solar.R, use="complete.obs")
[1] 0.3483417
Postoji još jedna funkcija koja se zove na.omit()
, a koja može biti korisna kada se radi s podacima koji nedostaju i automatski obavlja neke stvari koje smo prije radili. Možete ga koristiti na cijeloj datoteci ili na vektoru i uklonit će slučajeve s vrijednostima koje nedostaju i vratiti kompletan objekat.
airquality_clean2 <- na.omit(airquality)
dim(airquality_clean2)
[1] 111 6
Ako ga koristimo na vektoru, dobićemo ne samo vektor bez vrijednosti koje nedostaju, već i nešto više.
ozone_clean1 <- na.omit(airquality$Ozone)
ozone_clean1
[1] 41 36 12 18 28 23 19 8 7 16 11 14 18 14 34 6 30 11
[19] 1 11 4 32 23 45 115 37 29 71 39 23 21 37 20 12 13 135
[37] 49 32 64 40 77 97 97 85 10 27 7 48 35 61 79 63 16 80
[55] 108 20 52 82 50 64 59 39 9 16 78 35 66 122 89 110 44 28
[73] 65 22 59 23 31 44 21 9 45 168 73 76 118 84 85 96 78 73
[91] 91 47 32 20 23 21 24 44 21 28 9 13 46 18 13 24 16 13
[109] 23 36 7 14 30 14 18 20
attr(,"na.action")
[1] 5 10 25 26 27 32 33 34 35 36 37 39 42 43 45 46 52 53 54
[20] 55 56 57 58 59 60 61 65 72 75 83 84 102 103 107 115 119 150
attr(,"class")
[1] "omit"
Jedna stvar koju ćete često trebati je prekodirati varijable - stvoriti nove varijable čije se vrijednosti temelje na nekoj postojećoj varijabli. Naravno, postoje funkcije u R-u koje će vam to omogućiti, ali to možete vrlo lako učiniti i „ručno“. Počećemo sa potonjom opcijom, jer je u mnogim slučajevima lakše i pomaže vam da bolje razumijete što radite i što se događa sa datotekom.
Napomena:Kada prekodirate varijablu, pripazite da ne prepišete vrijednosti izvorne varijable. Možda će vam zatrebati kasnije u neke druge svrhe. Umjesto toga, stvorite novu varijablu u skupu podataka koja će sadržavati kodirane vrijednosti.
Pogledajmo varijablu Temp u skupu podataka o zračnosti s funkcijom hist()
.
hist(airquality$Temp)
Pretpostavimo da vam u neku svrhu ne treba da ova varijabla bude intervalna i želite je koristiti kao kategoričku varijablu, gdje ste razdvojili „Nisku“, „Srednju“ i „Visoku“ temperaturu. Ne postoje objektivni kriteriji za postavljanje pragova u raspodjeli, ali u ovom slučaju možemo viđeti da bi moglo imati smisla ako bi se temperature ispod 70 smatrale niskim, one između 70 i 90 smatrale srednjim, a one iznad 90 visokim. Pa kako bismo mogli stvoriti ovu novu varijablu sa odgovarajućim kategorijama?
Prvo, kreirajmo novu varijablu koja će sadržavati samo vrijednosti koje nedostaju.
airquality$Temp_new <- NA
Sada možemo koristiti uslovne izjave >
>=
<
<=
za mapiranje vrijednosti postojeće varijable na novu varijablu i popunjavanje po želji. Naredba airquality$Temp < 70
daće nam vektor logičkih vrijednosti TRUE
i FALSE
jednak dužini skupa podataka. Ovo možemo koristiti za odabir ovih mjesta u novoj varijabli đe je temperatura bila ispod 70 i ispuniti ih željenom vrijednošću, u ovom slučaju „niskom“. Ista logika može se koristiti za druge dvije kategorije. Kada se implementira u R kod, izgledaće ovako.
airquality$Temp_new[airquality$Temp < 70] <- "Low"
airquality$Temp_new[airquality$Temp >= 70 & airquality$Temp < 90] <- "Medium"
airquality$Temp_new[airquality$Temp >= 90] <- "High"
I tako smo stvorili novu kodiranu verziju varijable Temp. Početak novog skupa podataka izgledat će ovako.
head(airquality)
Ozone Solar.R Wind Temp Month Day Temp_new
1 41 190 7.4 67 5 1 Low
2 36 118 8.0 72 5 2 Medium
3 12 149 12.6 74 5 3 Medium
4 18 313 11.5 62 5 4 Low
5 NA NA 14.3 56 5 5 Low
6 28 NA 14.9 66 5 6 Low
U interesu prostora i jednostavnosti, moguće je sve vrijednosti rekodirati istvoremeno, koristeći funkciju recode()
iz paketa car
. Napravicemo novu varijablu “Temp_rec” iz orginalne “Temp” varijable.
airquality$Temp_rec <- recode(airquality$Temp, "lo:69= 'Low'; 70:89= 'Medium'; 90:hi='High'")
head(airquality)
Ozone Solar.R Wind Temp Month Day Temp_new Temp_rec
1 41 190 7.4 67 5 1 Low Low
2 36 118 8.0 72 5 2 Medium Medium
3 12 149 12.6 74 5 3 Medium Medium
4 18 313 11.5 62 5 4 Low Low
5 NA NA 14.3 56 5 5 Low Low
6 28 NA 14.9 66 5 6 Low Low