ajdastare / APPR-2017-18

Repozitorij z gradivi za predmet Analiza podatkov s programom R v študijskem letu 2017/18
MIT License
0 stars 0 forks source link

CSV in HTML tabela #1

Open ajdastare opened 6 years ago

ajdastare commented 6 years ago

Potrabovala bi nasvet, kako uredimo 2. tabelo - Stanovanjska prikrajsanost. Namreč v tabeli so podatk razvrščeni za vsak kriterij stanovanjske prikrajšanosti (slabo stanje stanovanja, kad ali prha v stanovanju itd...) in nato so razdeljeni po starostnih skupinah in spolu za vsako leto posebaj. Ne vem kako bi to razdelila v posamezne tabelice, morda za vsak kriterij posebaj tabelo.

Druga stvar, ne uspe mi uvozit html podatkov. Sem probla z vašo funkcijo ampak mi ne deluje.

Hvala že vnaprej.

jaanos commented 6 years ago

Uvoz bi šel nekako tako:

library(tidyr)

sl <- locale(encoding = "Windows-1250", decimal_mark = ".", grouping_mark = ",")
datoteka <- "podatki/stanovanjska_prikrajsanost.csv"
stan.pri <- read_delim(datoteka, ";", skip = 4, n_max = 68, trim_ws = TRUE, locale = sl) %>%
  fill(1:2) %>% drop_na(3)
stolpci <- read_csv2(datoteka, skip = 3, n_max = 1, col_names = FALSE,
                     col_types = cols(.default = col_integer())) %>% t() %>%
  cbind(data.frame(colnames(stan.pri) %>% strapplyc("^([^_]+)") %>% unlist())) %>% fill(1) %>%
  apply(1, paste, collapse = "")
stolpci[1:3] <- c("element", "starost", "spol")
colnames(stan.pri) <- stolpci
stan.pri <- melt(stan.pri, value.name = "stopnja", id.vars = 1:3, variable.name = "stolpec") %>%
  mutate(stolpec = parse_character(stolpec)) %>%
  transmute(leto = stolpec %>% strapplyc("^([0-9]+)") %>% unlist() %>% parse_number(),
            status = stolpec %>% strapplyc("([^0-9]+)$") %>% unlist() %>% factor(),
            element, starost, spol, stopnja)

Ideja je podobna kot pri anamkravanja#1, le da se leta preberejo posebej (lahko bi jih prebrali skupaj s preostankom tabele, a bi potem morali posebej poskrbeti za pretvorbo podatkov v števila). Posledično se kot imena stolpcev večkrat pojavijo iste vrednosti - read_delim (ki ga je namesto read_csv2 potrebno uporabiti zaradi neobičajne kombinacije uporabe podpičij kot ločil med celicami in pik za decimalke) potem pri ponovljenih imenih doda _1, _2 itd., kar je potrebno odstraniti.

Za zapolnjevanje podatkov v prvih dveh stolpcih (pa tudi za leta) in izpuščanje praznih vrstic se tukaj uporabita funkciji fill in drop_na iz knjižnice tidyr - svetujem, da jo uvoziš kar v lib/libraries.r (ta program lahko vedno zaženeš pred začetkom dela, da se ti naložijo ustrezne knjižnice).

Svetujem, da tudi za uvoz ostalih podatkov v obliki CSV uporabiš funkcijo read_delim iz knjižnice readr. Pri tem podaj ime uvožene datoteke relativno glede na glavni imenik projekta (npr. "podatki/stopnja_prenaseljenosti.csv") - če imaš v RStudiu odprt projekt, bo ta tvoj delovni imenik in ga ne spreminjaj. Če nimaš odprtega projekta (zgoraj desno piše Project: (None)), klikni tja, izberi Open Project..., nato pa poišči datoteko APPR-2017-18.Rproj v glavnem imeniku tvojega projekta.

Še to: ukaza View() ne vključuj v svoj program - zaenkrat lahko morda pustiš, da vidiš, kako izgledajo uvožene razpredelnice, bo pa postal moteč, ko se bodo razpredelnice pojavljale med prevajanjem poročila.

jaanos commented 6 years ago

Za podatke iz HTML bi se dalo uvoziti tako:

pre.moski <- read_html("podatki/prenaseljenost_eurostat_moski.htm") %>%
  html_node(xpath="//table[@class='infoData']") %>% html_table() %>%
  melt(value.name = "stopnja", id.vars = "timegeo", variable.name = "leto")
pre.zenske <- read_html("podatki/prenaseljenost_eurostat_zenske.htm") %>%
  html_node(xpath="//table[@class='infoData']") %>% html_table() %>%
  melt(value.name = "stopnja", id.vars = "timegeo", variable.name = "leto")
spoli <- c("moski", "zenske")
pre.moski$spol <- factor("moski", levels = spoli)
pre.zenske$spol <- factor("zenske", levels = spoli)
prenaseljenost <- rbind(pre.moski, pre.zenske) %>% mutate(stopnja = parse_number(stopnja, na = ":"))

Ker gre v obeh primerih za iste podatke, je seveda smiselno razpredelnici združiti. Za spol se tukaj uporabi faktor - smiselno bi bilo uporabiti faktor z istimi vrednostmi tudi drugod (če boš drugod imela še podatke za oba spola, bi torej bilo smiselno imeti to možnost v faktorju, tudi če se v razpredelnici ne pojavlja, saj bo tako mogoče ustrezno združevanje).

ajdastare commented 6 years ago

Zanima me kako naj zamenjam ime drzav iz "timegeo" v "Država" v 3. tabeli - Stopnja prenaseljenosti stanovanja v EU. Če zamenjam ime mi ne deluje koda posledično tudi zemljevid ne. Pomembno pa mi je zato, da se bo lepo v tabeli izpisalo "Država" namesto "timegeo".

jaanos commented 6 years ago

Najlažje bo, da to narediš kar pri prikazu:

prenaseljenost %>% rename(`država` = timegeo) %>% head %>% kable()
ajdastare commented 6 years ago

Dodala sem še 3. in 4. tabelo v uvozu. Ampak ne vem, če sem ju uredila optimalno. Rada bi ju prikazala v obliki grafa in bi potrebovala na x osi leta - kar je problem, saj leta niso v enem stolpcu.

jaanos commented 6 years ago

Razpredelnici bo treba pretvoriti v obliko tidy data, kar lahko storiš s funkcijo melt iz knjižnice reshape2. Za razpredelnico tabela_zadovoljstvo bi šlo nekako tako:

tabela_zadovoljstvo <- read_csv2(zadovoljstvo, skip = 4, n_max= 7, trim_ws = TRUE, locale = sl) %>%
  drop_na(3) %>% select(-1, -2) %>% rename(ocena = X3) %>%
  melt(id.vars = "ocena", variable.name = "leto", value.name = "odstotek") %>%
  mutate(leto = parse_number(leto))

Tukaj sem z zmanjšanjem n_max izločil postavko Povprečje, saj gre za drugi tip podatka - nanaša se na povprečno oceno, medtem ko so ostali podatki odstotki. Če bi želela uvoziti tudi podatke o povprečnih ocenah, bi ti sodili v svojo razpredelnico.

Naj opozorim še na težavo s kodiranjem znakov v datoteki zadovoljstvo2.csv - sklepam, da si datoteko odprla v Excelu in jo od tam shranila. Svetujem, da še enkrat pridobiš originalne podatke in jih še enkrat shraniš, vendar neposredno in brez odpiranja v Excelu. Je pa res, da kodiranje znakov vpliva le na postavko Povprečje, ki jo boš morda izločila (če pa se odločiš za uvažanje, bo potrebno uporabiti read_delim, da se bodo, tako kot spodaj, pravilno uvozile decimalne pike).

Podobno lahko uvoziš tudi razpredelnico breme_stanovanjskih_stroskov:

breme_stanovanjskih_stroskov <- read_delim(stroski, ";", skip = 3, n_max = 16, trim_ws = TRUE,
                                           locale = sl) %>% fill(1:2) %>% drop_na(3) %>%
  rename(gospodinjstvo = X1, velikost.bremena = X2) %>%
  melt(id.vars = c("gospodinjstvo", "velikost.bremena"),
       variable.name = "leto", value.name = "odstotek") %>%
  mutate(leto = parse_number(leto))

Presledkom (pa tudi šumnikom in drugim posebnim znakom) se v imenih stolpcev raje izogibaj.