Open nezahabjan opened 6 years ago
Takole nekako bi šel uvoz:
library(rjson)
library(tidyr)
link <- "http://apps.who.int/gho/athena/data/GHO/NCD_PAC,NCD_PAA?profile=xtab&format=html&x-topaxis=GHO;SEX&x-sideaxis=COUNTRY;YEAR;AGEGROUP&x-title=table&filter=AGEGROUP:YEARS18-PLUS;COUNTRY:*;SEX:*;"
json <- html_session(link) %>% read_html() %>% html_nodes(xpath="//script[not(@src)]") %>%
.[[1]] %>% html_text() %>% strapplyc("(\\{.*\\})") %>% unlist() %>% fromJSON() %>% .$Crosstable
matrika <- json$Matrix %>% sapply(. %>% sapply(. %>% .[[1]] %>% .$disp)) %>% t()
glava <- . %>% .$header %>% lapply(. %>% .[-1] %>% unlist() %>% { json$code[.+1] } %>%
sapply(. %>% .$disp))
stolpci <- json$Vertical$layer %>% unlist() %>% { json$dimension[.+1] } %>% sapply(. %>% .$disp)
colnames(matrika) <- glava(json$Horizontal) %>% sapply(paste, collapse = ",")
data <- glava(json$Vertical) %>% lapply(. %>% as.list() %>% setNames(stolpci)) %>%
bind_rows() %>% cbind(matrika) %>% melt(id.vars = 1:3) %>%
rename(Age.Group = `Age Group`) %>%
mutate(Country = factor(Country), Year = parse_number(Year),
Age.Group = factor(Age.Group),
value = parse_character(value, na = "No data"),
variable = parse_character(variable)) %>% drop_na(value) %>%
mutate(Indicator = variable %>% strapplyc("^([^,]+)") %>% unlist() %>% factor(),
Sex = variable %>% strapplyc("([^,]+)$") %>% unlist() %>% factor(),
Value = value %>% strapplyc("^([0-9.]+)") %>% unlist(),
Lower = value %>% strapplyc("\\[([0-9.]+)") %>% unlist(),
Upper = value %>% strapplyc("([0-9.]+)\\]") %>% unlist()) %>%
select(-variable, -value) %>% melt(measure.vars = c("Value", "Lower", "Upper"),
variable.name = "Statistic",
value.name = "Value") %>%
mutate(Value = parse_number(Value))
Za uvoz bo potrebna uporaba funkcij iz knjižnic rjson
in tidyr
. Svetujem, da njun uvoz opraviš kar v lib/libraries.r
- pred začetkom dela potem vedno poženi ta program, da se ti naložijo vse potrebne knjižnice. Naslov, s katerega se poberejo podatki, dobiš iz značke <iframe>
na tvoji povezavi - gre za spletno stran znotraj okvirja. Sami podatki v obliki JSON se pojavijo v bloku JavaScripta (značka script
) in jih je treba od tam izluščiti (od prvega zavitega oklepaja do zadnjega zavitega zaklepaja).
Funkcija fromJSON
iz knjižnice rjson
pretvori podatke v obliki JSON v gnezdene R-jeve sezname. Sami podatki so podani v polju Matrix
kot matrika (seznam seznamov) - celice vsebujejo še določene metapodatke, nas pa zanima polje disp
. Polji Horizontal
in Vertical
določata, katerim dimenzijam ustrezajo stolpci oziroma vrstice - vsebujeta polji layer
s kodami dimenzij in header
s kodami njihovih vrednosti. Sama imena dimenzij in njihovih vrednosti so podana v poljih dimension
in code
.
Podatki iz matrike se preberejo z dvema uporabama funkcije sapply
. Dobljeno matriko je potem potrebno transponirati (t()
). Za branje vrednosti dimenzij se potem pripravi funkcija glava
(notacija . %>% f(...)
je ekvivalentna function(x) { f(x, ...) }
); na podoben način se preberejo tudi imena stolpcev, ki ustrezajo dimenzijam za vrstice (torej država, leto, starostna skupina). Funkcija glava
se potem uporabi za določitev imen stolpcev matrike (te sedaj vsebujejo indikator in spol ločena z vejico, kar bo potrebno kasneje ločiti) ter za pripravo stolpcev s prvimi tremi dimenzijami - tem pripnemo našo matriko, da združimo vse podatke v eno razpredelnico.
Sedaj bo potrebno podatke spraviti v obliko tidy data - to naredi funkcija melt
iz knjižnice reshape2
, ki ji povemo, naj prve tri stolpce uporabi za dimenzije, poleg teh pa bo dodala še stolpca variable
in value
z imeni ostalih stolpcev in ustreznimi vrednostmi. Nato se stolpec Age Group
preimenuje tako, da nima presledka (odsvetujem tudi uporabo šumnikov in ostalih posebnih znakov v imenih stolpcev), ostalim stolpcem pa se nastavijo ustrezni tipi. Stolpec z vrednostmi vsebuje tri podatke (vrednost ter krajišči intervala zaupanja), tako da ga bomo zaenkrat pustili kot znakovni vektor, vrednosti No data
pa nadomestili z NA
, da lahko v naslednjem koraku ustrezne vrstice izpustimo s funkcijo drop_na
iz knjižnice tidyr
.
Sedaj vsebuje stolpec variable
dve vrednosti, stolpec value
pa tri, tako da s sledečim mutate
te vrednosti ločimo v nove stolpce, nato pa s select
izpustimo stolpca variable
in value
. Taki podatki še vedno niso v obliki tidy data, tako da ponovno uporabimo melt
- tokrat mu povemo, naj stolpce Value
, Lower
in Upper
uporabi za meritve, stolpcu z njihovimi imeni da ime Statistic
, stolpcu z vrednostmi pa Value
. Nazadnje slednji stolpec pretvorimo še v števila.
Še to: poskrbi, da bo zaganjanje programa uvoz.r
(po predhodnem uvozu knjižnic z libraries.r
) v celoti izvedlo uvoz brez napak. Ukaza View
ne uporabljaj v programu, saj bo povzročil, da se bodo razpredelnice odpirale med prevajanjem poročila. Svetujem tudi, da ne uporabljaš funkcij read.csv
(in ostalih read.*
s piko), pač pa za branje datotek CSV uporabljaš izključno funkcije iz knjižnice readr
(s podčrtajem namesto pike). Del programa, ki je ostal iz uvoza, pobriši (oziroma vsaj ne kliči teh funkcij, če jih že želiš imeti kot vzorec).
Očitno se je oblika podatkov JSON spet spremenila - tokrat bo treba popraviti le definicije spremenljivk matrika
, glava
in stolpci
na prejšnje stanje:
matrika <- json$Matrix %>% sapply(. %>% sapply(. %>% .[[1]] %>% .$disp)) %>% t()
glava <- . %>% .$header %>% lapply(. %>% .[-1] %>% unlist() %>% { json$code[.+1] } %>%
sapply(. %>% .$disp))
stolpci <- json$Vertical$layer %>% unlist() %>% { json$dimension[.+1] } %>% sapply(. %>% .$disp)
Nisem sicer prepričan, ali morda na različnih sistemih branje iz JSON deluje različno - če ti trenutna verzija že deluje, potem je najbrž že tako, in bi bilo potrebno zaznati, kateri način branja je pravi.
Najlepša hvala za opozorilo. Ko poženem celoten program za uvoz te tabele mi sicer tabelo izpiše, a kot napako vrne napako v številu dimenzije. Pri zagonu Vaše, popravljene kode, vrne tabelo brez napak, a ne tako urejeno kot je bila pred tem. Zanima me, ali se to dogaja zaradi spreminjanja same spletne strani iz katere je tabela pobrana, ali jaz naredim kaj narobe, čeprav kode za uvoz tabele v zadnjem času nisem več spreminjala.
Še enkrat se Vam zahvaljujem in Vas lepo pozdravljam, Neža Habjan
Dne 16. januar 2018 11:14 je Janoš Vidali notifications@github.com napisal/-a:
Očitno se je oblika podatkov JSON spet spremenila - tokrat bo treba popraviti le definicije spremenljivk matrika, glava in stolpci na prejšnje stanje:
matrika <- json$Matrix %>% sapply(. %>% sapply(. %>% .[[1]] %>% .$disp)) %>% t()glava <- . %>% .$header %>% lapply(. %>% .[-1] %>% unlist() %>% { json$code[.+1] } %>% sapply(. %>% .$disp))stolpci <- json$Vertical$layer %>% unlist() %>% { json$dimension[.+1] } %>% sapply(. %>% .$disp)
Nisem sicer prepričan, ali morda na različnih sistemih branje iz JSON deluje različno - če ti trenutna verzija že deluje, potem je najbrž že tako, in bi bilo potrebno zaznati, kateri način branja je pravi.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/nezahabjan/APPR-2017-18/issues/1#issuecomment-357914179, or mute the thread https://github.com/notifications/unsubscribe-auth/AbCN56BDq59i81zXCI4d_RLW6do_9P8eks5tLHZpgaJpZM4RIAuK .
Očitno so v zadnjem času (vsaj) dvakrat spremenili organizacijo podatkov v obliki JSON. Vmes so namreč odstranili spremenljivko Indicator
, pri čemer se je spremenila struktura; zdaj je struktura taka kot prvotna, a spremenljivke Indicator
ni več (kolikor se spomnim, je bila vrednost povsod enaka, tako da ni prišlo do izgube podatkov).
Skratka, nič ne delaš narobe - upajmo pa, da do novih sprememb ne bo prihajalo.
V redu, najlepša hvala za vse napotke.
lp, Neža
Dne 16. januar 2018 21:39 je Janoš Vidali notifications@github.com napisal/-a:
Očitno so v zadnjem času (vsaj) dvakrat spremenili organizacijo podatkov v obliki JSON. Vmes so namreč odstranili spremenljivko Indicator, pri čemer se je spremenila struktura; zdaj je struktura taka kot prvotna, a spremenljivke Indicator ni več (kolikor se spomnim, je bila vrednost povsod enaka, tako da ni prišlo do izgube podatkov).
Skratka, nič ne delaš narobe - upajmo pa, da do novih sprememb ne bo prihajalo.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/nezahabjan/APPR-2017-18/issues/1#issuecomment-358097596, or mute the thread https://github.com/notifications/unsubscribe-auth/AbCN5zVzYq4PymfB2p_BAIZy3SfjbpjYks5tLQkFgaJpZM4RIAuK .
Pozdravljeni,
pri pridobivanju podatkov s spletnih strani za projekt pri APPR, sem naletela na težavo pri eni od tabel. Ker je uvožena v CSV obliki zelo neuporabna, ste mi na vajah nekaj že pomagali z JSON obliko. Ker pa ni bilo dovolj časa, sva se dogovorila, da vam pošljem še link: http://apps.who.int/gho/data/node.main.A893?lang=en Prosila bi vas, če mi lahko pomagate.
Najlepša hvala, lep pozdrav, Neža Habjan