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

Osnovne operacije s datotekama

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.

Rukovanje nedostajućim vrijednostima

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"

Rekodiranje varijabli

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