Za današnje pedavanje je potrebno instaliriati SelectorGadget (Instalacija je moguća preko linka.). SelectorGadget je Chrome ekstenzija koja omogućava jednostavno pronalaženje CSS selektora na web stranicama. SelectorGadget je dostupan isključivo za Chrome. U slučaju da više volite Firefox, alternativa je ScrapeMate.
Prisjetite se da je rvest automatski instaliran sa tidyverse paketom. Ipak, ovo je prigodan način da instalirate i učitate sve prethodno pobrojane pakete ukoliko to niste već napravili:
## učitaj i instaliraj pakete
if (!require("pacman")) install.packages("pacman")
::p_load(tidyverse, rvest, lubridate, janitor, hrbrthemes)
pacman## ggplot2 tema (po želji)
theme_set(hrbrthemes::theme_ipsum())
Ovo predavanje se bavi preuzimanjem sadržaja sa web-a na vaše lokalno računalo. Svi već imamo iskustvo sa pregledom web sadržaja u browser-u (Chrome, Firefox,…) pa je vjerojatno logično da sadržaj koji gledamo negdje mora postojati u podatkovnom obliku. Važno je razumjeti da postoje dva osnovna načina na koja se web sadržaj prikazuje (engl.render) u browser-u:
Ovdje pogledajte ako vas zanima više detalja (uključujući primjere).
Za potrebe ovog predavanja, glavni su sljedeći elementi:
U ovom predavanju ćemo proći kroz glavne razlike između ova dva pristupa i dati pregled implikacija koje oni imaju za preuzimanje web sadržaja. Važno je istaknuti da webscraping uključuje ponešto “detektivskog” posla. Često će biti potrebno prilagoditi korake koje ćemo objasniti na predavanju prema podatcima koje želimo preuzeti, a procedure koje funkcioniraju na jednoj stranici neće nužno funkcionirati i na drugoj (ponekad neće funkcionirati ni na istoj nakon nekog vremena!). Zbog toga se je moguće reći da webscraping podjednako uključuje umjetnost (kreativnost) i znanost (razumijevanje).
Pozitivna strana svega je da server-strana i client-strana dozvoljavaju preuzimanje web sadržaja. Kao što ćemo uskoro vidjeti, preuzimanje podataka sa web stranice koja funkcionira na client-strani (API) je često jednostavnije, pogotovo kada nam je cilj preuzeti veću (bulk) količinu podataka. Za webscraping vrijedi općenito pravilo: ako vidite podatke u browseru, možete ih i preuzeti.
Prethodna rečenica ne uzima u obzir važne etičke i zakonske aspekte preuzimanja sadržaja sa interneta. Samo zato što možete nešto preuzeti sa interneta, ne zanči da biste to i trebali učiniti. Vaša je odgovornost procijeniti da li web stranica polaže zakonska ograničenja na sadržaj koji se tamo nalazi. Alati koje ćemo koristiti u ovom predavanju su uistinu moćni, mogu prenapregnuti server i izazvati poteškoće u radu ili pad web stranice. Glavna maksima kod webscraping-a je stoga “budite pristojni”!
Glavni paket u R-u za preuzimanje web sadržaja na strani severa je rvest (link). To je jednostavan, ali moćan paket za webscraping inspiriran Python-ovom Beautiful Soup (link) platformom, ali uz dodatne tidyverse funkcionalnosti :-). rvest je osmišljen za rad sa stranicama koje su procesuirane na strani severa i zbog toga zahtijeva određeno razumijevanje CSS selektora…pa pogledajmo o čemu se radi…
Za informacije o CSS (i.e Cascading Style Sheets) i SelectorGadget-u pročitajte više na interentu. Ukratko, CSS je jezik koji određuje izgled HTML dokumenata (uključujući i web stranice) tako što omogućuje browseru skup pravila za prikaz koja se formiraju na osnovi:
Za preuzimanje podataka sa web stranice je bitno identificirati CSS selektore sadržaja koji želimo skinuti jer tako izoliramo djelove stranice od interesa. Upravo tu dolazi do izražaja korisnost SelectorGadget-a. U ovom predavanju ćemo proći kroz primjer korištenja SelectorGadget-a, no preporučljivo je pogledati vignette prije nastavka.
Stavimo sve ovo u praktični kontekst kroz preuzimanje podataka sa Wikipedia stranice Men’s 100 metres world record progression.
Prvo, otvorite ovu stranicu u vašem browser-u. Upoznajte se sa strukturom stranice: Kakve objekte stranica sadrži? Koliko ima tablica? Da li tablice imaju iste kolone? Kakvi su rasponi redova i kolona? itd.
Nakon što ste se upoznali sa strukturom stranice, učitajte cijelu stranicu u R koristeći rvest::read_html()
funkciju:
# library(rvest) ## već učitano
<- read_html("http://en.wikipedia.org/wiki/Men%27s_100_metres_world_record_progression")
m100 # pogledaj objekt
m100
## {html_document}
## <html class="client-nojs" lang="en" dir="ltr">
## [1] <head>\n<meta http-equiv="Content-Type" content="text/html; charset=UTF-8 ...
## [2] <body class="mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-0 ns-subject ...
Kao što vidite, ovo je XML dokument1 koji sadrži sve potrebno za procesuiranje Wikipedia stranice. To je otprilike kao da promatrate cjeli .pdf dokument (specifikacije, formule, itd.), a želite preuzeti samo jednu tablicu ili dio poglavlja.
Pokušajmo sada izolirati prvu tablicu sa naslovom Unofficial progression before the IAAF. Kao što je objašnjeno u rvest vignette-i, možemo koristiti funkciju rvest::html_nodes()
kako bismo izolirali i preuzeli ovu tablicu iz HTML dokumenta kroz specifikaciju odggovarajućih CSS selektora. Potom je potrebno pretvoriti objekt u data.frame koristeći rvest::html_table()
funkciju. Preporuča se korištenje fill=TRUE
argumenta u ovom slučaju, jer će se u suprotnom javiti problemi sa formatiranjem redova zbog razmaka u Wiki tablici.
Koristiti ćemo SelectorGadget za identifikaciju CSS selektora. U ovom slučaju je riječ o “div+ .wikitable :nth-child(1)” elementu. Pogledajmo kako to funkcionira:
%>%
m100 html_nodes("div+ .wikitable :nth-child(1)") %>%
html_table(fill=TRUE)
## Error in matrix(unlist(values), ncol = width, byrow = TRUE): 'data' must be of a vector type, was 'NULL'
Izgleda da nešto nije u redu…!? Dobili smo error. Bez da ulazimo u detalje, valja znati da je SelectorGadget ponekad neprecizan….iako je riječ o izvrsnom alatu koji uglavnom radi dobro. Ipak, ponekad ono što izgleda kao dobar selektor (i.e. naglašeno žuto) nije točno ono što tražimo. Ovaj error je namjerno prikazan radi skretanja pažnje na potencijalne probleme koji se mogu javiti pri korištenju SelectorGadget-a. Treba još jednom reći: Webscraping je u jednakoj mjeri umjetnost i znanost!
Na sreću, postoji i precizniji način određivanja točnog selektora, a odnosi se na korištenje “inspect web element” opcije koju ima većina modernih browser-a. U ovom slučaju koristimo (Ctrl+Shift+I, ili desni klik miša i izaberi “Inspect”). Potom ćemo proći kroz source elemente dok Chrome ne istakne tablicu koja nas zanima. Nakon toga opet desni klik miša i izaberite Copy -> Copy selector. Pogledajte opisanu proceduru:
Koristeći ovu metodu dobijemo CSS selektor “table.wikitable:nth-child(9) > tbody:nth-child(1)”. Pogledajmo da li će ovaj put sve funkcionirati bez error-a. Ponovno ćemo koristiti rvest::html_table(fill=TRUE)
funkciju za prebacivanje tablice u data.frame:
%>%
m100 html_nodes("table.wikitable:nth-child(9) > tbody:nth-child(1)") %>%
html_table(fill=TRUE)
## [[1]]
## # A tibble: 21 x 5
## Time Athlete Nationality `Location of races` Date
## <dbl> <chr> <chr> <chr> <chr>
## 1 10.8 Luther Cary United States Paris, France July 4, 1~
## 2 10.8 Cecil Lee United Kingdom Brussels, Belgium September~
## 3 10.8 Étienne De Ré Belgium Brussels, Belgium August 4,~
## 4 10.8 L. Atcherley United Kingdom Frankfurt/Main, Germany April 13,~
## 5 10.8 Harry Beaton United Kingdom Rotterdam, Netherlands August 28~
## 6 10.8 Harald Anderson-Arbin Sweden Helsingborg, Sweden August 9,~
## 7 10.8 Isaac Westergren Sweden Gävle, Sweden September~
## 8 10.8 Isaac Westergren Sweden Gävle, Sweden September~
## 9 10.8 Frank Jarvis United States Paris, France July 14, ~
## 10 10.8 Walter Tewksbury United States Paris, France July 14, ~
## # ... with 11 more rows
#mw-content-text > div > table:nth-child(8)
Sjajno, čini se da sve radi! Sada ćemo sve pripisati novom objektu pre_iaaf
i još jednom provjeriti objektnu klasu (class).
<-
pre_iaaf %>%
m100 html_nodes("table.wikitable:nth-child(9) > tbody:nth-child(1)") %>%
html_table(fill=TRUE)
class(pre_iaaf)
## [1] "list"
Izgleda da smo uistinu dobili list-u! Pretvorimo sada stvarno taj objekt u data.frame. To je moguće učiniti na više načina. U ovom slučaju ćemo koristiti dplyr::bind_rows()
funkciju. Riječ je o izvrsnom načinu za pretvaranje više list-a u jedan data.frame.2
## pretvori list-u u data_frame
# pre_iaaf <- pre_iaaf[[1]] ## također moguće
# library(tidyverse) ## A++već učitano
<-
pre_iaaf %>%
pre_iaaf bind_rows() %>%
as_tibble()
pre_iaaf
## # A tibble: 21 x 5
## Time Athlete Nationality `Location of races` Date
## <dbl> <chr> <chr> <chr> <chr>
## 1 10.8 Luther Cary United States Paris, France July 4, 1~
## 2 10.8 Cecil Lee United Kingdom Brussels, Belgium September~
## 3 10.8 Étienne De Ré Belgium Brussels, Belgium August 4,~
## 4 10.8 L. Atcherley United Kingdom Frankfurt/Main, Germany April 13,~
## 5 10.8 Harry Beaton United Kingdom Rotterdam, Netherlands August 28~
## 6 10.8 Harald Anderson-Arbin Sweden Helsingborg, Sweden August 9,~
## 7 10.8 Isaac Westergren Sweden Gävle, Sweden September~
## 8 10.8 Isaac Westergren Sweden Gävle, Sweden September~
## 9 10.8 Frank Jarvis United States Paris, France July 14, ~
## 10 10.8 Walter Tewksbury United States Paris, France July 14, ~
## # ... with 11 more rows
Sada je potrebno urediti nazive varijabli (kolona)…ovdje koristimo janitor::clean_names()
funkciju, koja je napravljena isključivo za tu namjenu. (Q: Na koji još način se to može učiniti?)
# library(janitor) ## učitano
<-
pre_iaaf %>%
pre_iaaf clean_names()
pre_iaaf
## # A tibble: 21 x 5
## time athlete nationality location_of_races date
## <dbl> <chr> <chr> <chr> <chr>
## 1 10.8 Luther Cary United States Paris, France July 4, 1~
## 2 10.8 Cecil Lee United Kingdom Brussels, Belgium September~
## 3 10.8 Étienne De Ré Belgium Brussels, Belgium August 4,~
## 4 10.8 L. Atcherley United Kingdom Frankfurt/Main, Germany April 13,~
## 5 10.8 Harry Beaton United Kingdom Rotterdam, Netherlands August 28~
## 6 10.8 Harald Anderson-Arbin Sweden Helsingborg, Sweden August 9,~
## 7 10.8 Isaac Westergren Sweden Gävle, Sweden September~
## 8 10.8 Isaac Westergren Sweden Gävle, Sweden September~
## 9 10.8 Frank Jarvis United States Paris, France July 14, ~
## 10 10.8 Walter Tewksbury United States Paris, France July 14, ~
## # ... with 11 more rows
Još je potrebno urediti “date” varijablu tako da R može prepoznati string vrijednosti kao datum.
# library(lubridate) ## već učitano
<-
pre_iaaf %>%
pre_iaaf mutate(date = mdy(date))
pre_iaaf
## # A tibble: 21 x 5
## time athlete nationality location_of_races date
## <dbl> <chr> <chr> <chr> <date>
## 1 10.8 Luther Cary United States Paris, France 1891-07-04
## 2 10.8 Cecil Lee United Kingdom Brussels, Belgium 1892-09-25
## 3 10.8 Étienne De Ré Belgium Brussels, Belgium 1893-08-04
## 4 10.8 L. Atcherley United Kingdom Frankfurt/Main, Germany 1895-04-13
## 5 10.8 Harry Beaton United Kingdom Rotterdam, Netherlands 1895-08-28
## 6 10.8 Harald Anderson-Arbin Sweden Helsingborg, Sweden 1896-08-09
## 7 10.8 Isaac Westergren Sweden Gävle, Sweden 1898-09-11
## 8 10.8 Isaac Westergren Sweden Gävle, Sweden 1899-09-10
## 9 10.8 Frank Jarvis United States Paris, France 1900-07-14
## 10 10.8 Walter Tewksbury United States Paris, France 1900-07-14
## # ... with 11 more rows
Sada imamo čisti data.frame i mogli bismo napraviti vizualizaciju pre-IAAF podataka. Neka to još malo pričeka dok ne preuzmemo ostatak tablica sa stranice…
Nastavimo sada sa sljedećom tablicom:
<- read_html("http://en.wikipedia.org/wiki/Men%27s_100_metres_world_record_progression")
m100 <-
iaaf_76 %>%
m100 html_nodes("table.wikitable:nth-child(15) > tbody:nth-child(1)") %>%
html_table(fill=TRUE)
Potrebno je popuniti vrijednosti koje nedostaju (NA!) za athlete varijablu (to zahtijeva malo drugačiju proceduru nego u prošloj tablici. Q:Zašto!?) i urediti datume.
<-
iaaf_76 %>%
iaaf_76 mutate(athlete = ifelse(athlete=="", lag(athlete), athlete)) %>%
mutate(date = mdy(date))
Čini se da su neki datumi uvezeni u čudnom zapisu zbog loših podataka (jednaki datumi za različite dane) u tablici:
%>% tail(20) iaaf_76
## # A tibble: 20 x 8
## time wind auto athlete nationality location_of_race date ref
## <dbl> <chr> <dbl> <chr> <chr> <chr> <date> <chr>
## 1 10 "2.0" 10.2 Jim Hines United Sta~ Modesto, USA 1967-05-27 "[2]"
## 2 10 "1.8" NA Enrique F~ Cuba Budapest, Hungary 1967-06-17 "[2]"
## 3 10 "0.0" NA Paul Nash South Afri~ Krugersdorp, Sout~ 1968-04-02 "[2]"
## 4 10 "1.1" NA Oliver Fo~ United Sta~ Albuquerque, USA 1968-05-31 "[2]"
## 5 10 "2.0" 10.2 Charles G~ United Sta~ Sacramento, USA 1968-06-20 "[2]"
## 6 10 "2.0" 10.3 Roger Bam~ France Sacramento, USA 1968-06-20 ""
## 7 9.9 "0.8" 10.0 Jim Hines United Sta~ Sacramento, USA 1968-06-20 "[2]"
## 8 9.9 "0.8" 10.1 Ronnie Ra~ United Sta~ Sacramento, USA 1968-06-20 ""
## 9 9.9 "0.9" 10.1 Charles G~ United Sta~ Sacramento, USA 1968-06-20 ""
## 10 9.9 "0.3" 9.95 Jim Hines United Sta~ Mexico City, Mexi~ 1968-10-14 "[2]"
## 11 9.9 "0.0" NA Eddie Hart United Sta~ Eugene, USA 1972-07-01 "[2]"
## 12 9.9 "0.0" NA Rey Robin~ United Sta~ Eugene, USA 1972-07-01 ""
## 13 9.9 "1.3" NA Steve Wil~ United Sta~ Los Angeles, USA 1974-06-21 "[2]"
## 14 9.9 "1.7" NA Silvio Le~ Cuba Ostrava, Czechosl~ 1975-06-05 "[2]"
## 15 9.9 "0.0" NA Steve Wil~ United Sta~ Siena, Italy 1975-07-16 "[2]"
## 16 9.9 "-0.2" NA Steve Wil~ United Sta~ Berlin, Germany 1975-08-22 "[2]"
## 17 9.9 "0.7" NA Steve Wil~ United Sta~ Gainesville, USA 1976-03-27 "[2]"
## 18 9.9 "0.7" NA Harvey Gl~ United Sta~ Columbia, USA 1976-04-03 "[2]"
## 19 9.9 "" NA Harvey Gl~ United Sta~ Baton Rouge, USA 1976-05-01 "[2]"
## 20 9.9 "1.7" NA Don Quarr~ Jamaica Modesto, USA 1976-05-22 "[2]"
Problem ćemo riješiti tako da vrijednosti popunimo sa prethohdnim realizacijama (lag-ovima). Isprobajmo za početak:
%>%
iaaf_76 mutate(date = ifelse(is.na(date), lag(date), date))
## # A tibble: 54 x 8
## time wind auto athlete nationality location_of_race date ref
## <dbl> <chr> <dbl> <chr> <chr> <chr> <dbl> <chr>
## 1 10.6 "" NA Donald Lippincott United Sta~ Stockholm, Swed~ -20998 [2]
## 2 10.6 "" NA Jackson Scholz United Sta~ Stockholm, Swed~ -18004 [2]
## 3 10.4 "" NA Charley Paddock United Sta~ Redlands, USA -17785 [2]
## 4 10.4 "0.0" NA Eddie Tolan United Sta~ Stockholm, Swed~ -14756 [2]
## 5 10.4 "" NA Eddie Tolan United Sta~ Copenhagen, Den~ -14739 [2]
## 6 10.3 "" NA Percy Williams Canada Toronto, Canada -14390 [2]
## 7 10.3 "0.4" 10.4 Eddie Tolan United Sta~ Los Angeles, USA -13667 [2]
## 8 10.3 "" NA Ralph Metcalfe United Sta~ Budapest, Hunga~ -13291 [2]
## 9 10.3 "" NA Eulace Peacock United Sta~ Oslo, Norway -12932 [2]
## 10 10.3 "" NA Chris Berger Netherlands Amsterdam, Neth~ -12912 [2]
## # ... with 44 more rows
Izgleda da su datumi postali numerička varijabla (brojevi). Razlog je korištenje base R funkcije ifelse()
(probajte pronaći na Google-u). U ovom će slučaju biti bolja tidyverse ekvivalentna funkcija, i.e. if_else()
:
<-
iaaf_76 %>%
iaaf_76 mutate(date = if_else(is.na(date), lag(date), date))
iaaf_76
## # A tibble: 54 x 8
## time wind auto athlete nationality location_of_race date ref
## <dbl> <chr> <dbl> <chr> <chr> <chr> <date> <chr>
## 1 10.6 "" NA Donald Lip~ United Sta~ Stockholm, Sweden 1912-07-06 [2]
## 2 10.6 "" NA Jackson Sc~ United Sta~ Stockholm, Sweden 1920-09-16 [2]
## 3 10.4 "" NA Charley Pa~ United Sta~ Redlands, USA 1921-04-23 [2]
## 4 10.4 "0.0" NA Eddie Tolan United Sta~ Stockholm, Sweden 1929-08-08 [2]
## 5 10.4 "" NA Eddie Tolan United Sta~ Copenhagen, Denma~ 1929-08-25 [2]
## 6 10.3 "" NA Percy Will~ Canada Toronto, Canada 1930-08-09 [2]
## 7 10.3 "0.4" 10.4 Eddie Tolan United Sta~ Los Angeles, USA 1932-08-01 [2]
## 8 10.3 "" NA Ralph Metc~ United Sta~ Budapest, Hungary 1933-08-12 [2]
## 9 10.3 "" NA Eulace Pea~ United Sta~ Oslo, Norway 1934-08-06 [2]
## 10 10.3 "" NA Chris Berg~ Netherlands Amsterdam, Nether~ 1934-08-26 [2]
## # ... with 44 more rows
Zadnja tablica također sadržava neke specifičnosti vezano uz razmake u redovima i ostalo…pa smo ju uredili…bez da ulazimo u detalje oko načina… Probajte sami izvršiti sljedeći kod! Ovdje sve izvršavamo u jednom komadu (engl. chunk) koda:
<-
iaaf %>%
m100 html_nodes("table.wikitable:nth-child(20) > tbody:nth-child(1)") %>%
html_table(fill=TRUE)
## Pretvori list-u u data_frame i uredi nazve varijabli (kolona)
<-
iaaf %>%
iaaf bind_rows() %>%
as_tibble() %>%
clean_names()
## Uredi datum.
<-
iaaf %>%
iaaf mutate(date = mdy(date))
## Usain Bolt je pripisan Asafa Powell-u zbog
## razmaka u Wikipedia redovima (ista zemlja, i dr.). E.g.
%>% tail(8) iaaf
## # A tibble: 8 x 9
## time wind auto athlete nationality location_of_race date notes_note_2
## <dbl> <chr> <dbl> <chr> <chr> <chr> <date> <chr>
## 1 9.77 1.6 9.77 Asafa ~ Jamaica Athens, Greece 2005-06-14 [2]
## 2 9.77 1.7 9.77 Justin~ United Sta~ Doha, Qatar 2006-05-12 [5][9][note~
## 3 9.77 1.5 9.76 Asafa ~ Jamaica Gateshead, Unit~ 2006-06-11 [2]
## 4 9.77 1.0 9.76 Asafa ~ Jamaica Zürich, Switzer~ 2006-08-18 [2]
## 5 9.74 1.7 9.74 Asafa ~ Jamaica Rieti, Italy 2007-09-09 [1][10]
## 6 9.72 1.7 NA Usain ~ Jamaica New York, USA 2008-05-31 [2]
## 7 9.69 0.0 9.68 Usain ~ Jamaica Beijing, China 2008-08-16 OR[2]
## 8 9.58 0.9 9.57 Usain ~ Jamaica Berlin, Germany 2009-08-16 CR[1][11][1~
## # ... with 1 more variable: duration_of_record <chr>
## Popravljeno
<-
iaaf %>%
iaaf mutate(
athlete = ifelse(athlete==nationality, NA, athlete),
athlete = ifelse(!is.na(as.numeric(nationality)), NA, athlete),
athlete = ifelse(nationality=="Usain Bolt", nationality, athlete),
nationality = ifelse(is.na(athlete), NA, nationality),
nationality = ifelse(athlete==nationality, NA, nationality)
%>%
) fill(athlete, nationality)
Povežimo odvojena razdoblja u jedan data.frame. Ponovno ćemo koristiti funkciju dplyr:: bind_rows()
i zadržati samo zajedničke varijable. Također ćemo dodati varijablu (kolonu) koja se refeira na razdoblje (naziv) za koje su zabilježeni rezultati:
<-
wr100 bind_rows(
%>% select(time, athlete, nationality:date) %>% mutate(era = "IAAF"),
pre_iaaf %>% select(time, athlete, nationality:date) %>% mutate(era = "Pred-automatska"),
iaaf_76 %>% select(time, athlete, nationality:date) %>% mutate(era = "Moderna")
iaaf
) wr100
## # A tibble: 99 x 7
## time athlete nationality location_of_rac~ date era location_of_race
## <dbl> <chr> <chr> <chr> <date> <chr> <chr>
## 1 10.8 Luther ~ United Sta~ Paris, France 1891-07-04 IAAF <NA>
## 2 10.8 Cecil L~ United Kin~ Brussels, Belgi~ 1892-09-25 IAAF <NA>
## 3 10.8 Étienne~ Belgium Brussels, Belgi~ 1893-08-04 IAAF <NA>
## 4 10.8 L. Atch~ United Kin~ Frankfurt/Main,~ 1895-04-13 IAAF <NA>
## 5 10.8 Harry B~ United Kin~ Rotterdam, Neth~ 1895-08-28 IAAF <NA>
## 6 10.8 Harald ~ Sweden Helsingborg, Sw~ 1896-08-09 IAAF <NA>
## 7 10.8 Isaac W~ Sweden Gävle, Sweden 1898-09-11 IAAF <NA>
## 8 10.8 Isaac W~ Sweden Gävle, Sweden 1899-09-10 IAAF <NA>
## 9 10.8 Frank J~ United Sta~ Paris, France 1900-07-14 IAAF <NA>
## 10 10.8 Walter ~ United Sta~ Paris, France 1900-07-14 IAAF <NA>
## # ... with 89 more rows
Vizualizaciju podataka konačno možemo napraviti na način:
%>%
wr100 ggplot(aes(x=date, y=time, col=fct_reorder2(era, date, time))) +
geom_point(alpha = 0.7) +
labs(
title = "Evolucija svjetskog rekorda -- Sprint na 100m",
x = "Datum", y = "Postignuce (100m u sek)",
caption = "Izvor: Wikipedia"
+
) theme(legend.title = element_blank()) ## Makni legendu
rvest
paket za učitavanje HTML dokumenta u R i parsanje nodova od interesa. read_html(URL) %>% html_nodes(CSS_SELECTORS) %>% html_table()
. ?html_text
). Probajte koristiti novo-stečene rvest
vještine na nekom od (mnogih) online tutoriala. Pri tome ne zaboravite:
Smomenuli smo princip “lijepog ponašanja” na web-u…ovdje vrijedi istaknuti polite paket (link). Paket omogućava korisne alate u maniri dobrog ponašanja na web-u poput provjere dopuštenja i opterećenja stranice sa koje preuzimamo sadržaj. Paket se također nadopunjuje sa rvest pristupom koji smo prikazali u predavanju.
Preuzeti podatci predstavljaju dobru osnovu za statističku analizu pa ih je dobro promotriti u tom kontekstu. kako biste modelirali napredak u svjetskim sprint rekordima na 100m? Zamislite da želite predvidjeti današnji svjetski rekord u 2005. godini! Kako bi se predviđanje odnosilo na aktualni rekord iz 2009. godine (i.e. Usain Bolt, 9.58 sec)? Kako biste to interpretirali?
Savjet: Pogledajte ?broom::tidy()
funkciju za ekstrakciju regresijskih koeficijenata u prikladnom data frame objektu. Već smo vidjeli geom_smooth()
funkciju u predavanju o vizualizaciji podataka. Za ideje o vizualizaciji predviđanja pogledajte Poglavlje 23 R4DS knjige, ili Poglavlje 6.4 SocViz knjige. Razmotrite base::predict()
funkcij. Alternativno koristite tidyverse’s modelr
paket.