Lataa luento omalle koneelle

download.file("https://gitlab.com/utur2016/content/raw/master/session3_transform_luento.Rmd",
              destfile="session3_transform_luento.Rmd")
file.edit("session3_transform_luento.Rmd")

1 Datan manipuloinnin perusteet dplyr-paketilla

Kerrataan data-manipulaation perusverbit dplyr-paketista viime viikolta.

  • filter() - valitse rivejä datasta
  • arrange() - järjestä rivit uudelleen
  • select() - valitse muuttujia
  • mutate() - luo uusia muuttujia olemassaolevista muuttujista
  • summarise()- tiivistä muuttujan arvo yhteen lukuun
  • group_by() - mahdollistaa yllä olevien viiden verbin käytön ryhmittäisen käytön

Tidyverse-maailmassa yllä olevista kuudesta verbistä voidaan puhua datamanipulaation kielenä.

Kaikki toimivat samalla tapaa

  1. Ensimmäinen argumentti on data
  2. Seuraavat argumentit kuvaavat mitä datalle tehdään käyttäen muuttujanimiä ilman lainausmerkkejä
  3. Tulos on aina tibble/data.frame

Eli käyttäen kotitehtävistä tuttua dataa..

library(tidyverse)
d <-read.csv("https://vincentarelbundock.github.io/Rdatasets/csv/plm/Males.csv", stringsAsFactors = FALSE)
d <- as_tibble(d)
d

…voidaan ensin valita naimissa olevat ja liittoon kuuluvat

d %>% dplyr::filter(union == "yes", married == "yes")

Sen jälkeen järjestetään data aineiston nousevaan järjestykseen keräysvuoden ja tapausten numeroiden mukaan.

d %>% dplyr::filter(union == "yes", married == "yes") %>% 
  arrange(year,nr)

Sitten valitaan ainoastaan muuttujat year, school, exper, union, wage, industry

d %>% dplyr::filter(union == "yes", married == "yes") %>% 
  arrange(year,nr) %>% 
  select(year,school,exper,union,wage,industry)

Sen jölkeen luodaan uusi muuttuja school_exper jossa lasketaan yhteen kouluvuodet ja työkokemus

d %>% dplyr::filter(union == "yes", married == "yes") %>% 
  arrange(year,nr) %>% 
  select(year,school,exper,wage,industry) %>% 
  mutate(school_exper = school + exper)

Sitten lisätään uusi muuttuja jossa on school_exper-muuttujan luokittain keskipalkat

d %>% dplyr::filter(union == "yes", married == "yes") %>% 
  arrange(year,nr) %>% 
  select(year,school,exper,wage,industry) %>% 
  mutate(school_exper = school + exper) %>% 
  group_by(school_exper) %>% mutate(mean_wage = mean(wage))

Ja aivan lopuksi vielä summataan alkuperäisestä datasta liittoon kuulumattomien ja kuuluvien mediaanipalkat eri vuosina

d %>% group_by(year,union) %>% 
  summarise(yearly_median_wage = median(wage))

2 Tidy-datan perusteet

Lähde: http://r4ds.had.co.nz/tidy-data.html

“Happy families are all alike; every unhappy family is unhappy in its own way.” –– Leo Tolstoy

“Tidy datasets are all alike, but every messy dataset is messy in its own way.” –– Hadley Wickham

Alla sama data neljällä eri tavalla järjestettynä. Kaikissa datoissa on neljä muuttujaa country,year,population ja cases, mutta jokainen on järjestetty eri tavalla.

library(tidyverse)
data("table1")
table1
data("table2")
table2
data("table3")
table3

Kahdessa eri datassa:

data("table4a")
table4a
data("table4b")
table4b

Kaikki datat esittävät siis samaa pohjalla olevaa dataa, mutta ne eivät ole yhtä helppoja käyttää. Tidy data -ajattelussa pyritään yhdenmukaiseen datan rakenteeseen, tidy data:aan, jolloin datan kanssa työskentelyn helpottuu etenkin ns. tidyverse:en kuuluvilla työkaluilla joita tällä kurssillä käytämme. (Lue myös The tidy tools manifesto)

2.1 tidy-datan kolme ehtoa

Data on tidy kun se täyttää seuraavat toisistaan riippuvaiset kolme ehtoa:

  1. Jokainen muuttuja on omassa sarakkeessaan
  2. Jokainen havainto on omalla rivillään
  3. jokainen arvo on omassa solussaan
Kuva: Ehdot visualisoituna. Lähde: http://r4ds.had.co.nz/images/tidy-1.png

Kuva: Ehdot visualisoituna. Lähde: http://r4ds.had.co.nz/images/tidy-1.png

Koska ehdot ovat riippuvaisia toisistaan ja on mahdotonta täyttää kahta ilman kolmatta voi tidy:n datan ehtoina pitää seuraavia kahta:

  1. Jokainen data omana tibble:nä (tai data.frame:na)
  2. Jokainen muuttuja omassa sarakkeessaan

Yllä olevissa taulukoissa ainoastaan table1 on tidy ja siis ainoa, jossa kukin muuttuja on omassa sarakkeessaan.

2.2 Tidy:n datan hyödyt

  1. On ylipäätään hyödyllistä valita yksi johdonmukainen tapa datan säilyttämiseen. Kun datat ovat tidy-muodossa on helpompaa opetella ko. rakennetta edellyttäviä data-analyysin työkaluja.
  2. Muuttujien laittamisella omiin sarakkeihin pystyy myös hyödyntää paremmin R:n vektoroitua toimintatapaa.

Seuraavassa pari esimerkkiä siitä, miten helppoa on työskennellä tidy:n datan kanssa

table1 %>% 
  mutate(vaestosuhde = cases / population * 10000)
table1 %>% 
  count(year, wt = cases)
library(ggplot2)
ggplot(table1, aes(x=year, y=cases)) + 
  geom_line(aes(group = country,colour = country)) + 
  geom_point(aes(colour = country))

Lasketaan vastaava vaestosuhde table2 ja table4a:sta ja table4b:stä.

table2 %>% 
  tidyr::spread(., key = type, value = count, 3) %>% 
  dplyr::mutate(vaestosuhde = cases / population * 10000)
t4a <- table4a %>% tidyr::gather(., key = year, value = cases, 2:3)
t4b <- table4b %>% tidyr::gather(., key = year, value = population, 2:3)
t4a %>% left_join(t4b) %>% 
  dplyr::mutate(vaestosuhde = cases / population * 10000)

3 Tidyr-paketin perusfunktiot

Luodaan esin data nimeltä tapaukset

tapaukset <- dplyr::data_frame(country = c("FR", "DE", "US", "FR", "DE", "US", "FR", "DE", "US"),
                 year = c(2011,2011,2011,2012,2012,2012,2013,2013,2013),
                 n = c(7000,5800,15000,6900,6000,14000,7000,6200,13000)) %>%  
  spread(., year, n)
tapaukset

3.1 gather

Leveässä muodossa olevan datan kokoaminen pitkään muotoon

tapaukset <- gather(data = tapaukset,  # data
                 key = year, # avainmuuttujan arp
                 value = n, # name of valut var
                 2:4) # variables NOT tidy
tapaukset

3.2 spread

pitkän datan levittäminen

spread(data=tapaukset,  # data
       key=year, # class-var
       value=n) # amount

3.3 separate

Luodaan data

myrskyt <- dplyr::data_frame(storm = c("Alberto", "Alex", "Allison", "Ana", "Arlene", "Arthur"),
                     wind = c(110,45,65,40,50,45),
                     pressure = c(1007,1009,1005,1013,1010,1010),
                     date = as.Date(c("2000-08-03", "1998-07-27", "1995-06-03", "1997-06-30", "1999-06-11", "1996-06-17")))
myrskyt
myrskyt2 <- separate(data = myrskyt, col = date, into = c("year", "month", "day"), sep = "-")
myrskyt2

3.4 unite

unite(myrskyt2, "date", year, month, day, sep = "/")

4 Pari omatoimiharjoitusta

Luodaan datat

library(tidyverse)
# cases-data
cases <- dplyr::data_frame(country = c("FR", "DE", "US", "FR", "DE", "US", "FR", "DE", "US"),
                 year = c(2011,2011,2011,2012,2012,2012,2013,2013,2013),
                 n = c(7000,5800,15000,6900,6000,14000,7000,6200,13000)) %>%  
  spread(., year, n)
cases
# pollution-data
pollution <- dplyr::data_frame(city = c("New York", "New York", "London", "London", "Beijing", "Beijing"),
                 size = c("large", "small", "large", "small", "large", "small"),
                 amount = c(23,14,22,16,121,56))
pollution
# storms
storms <- dplyr::data_frame(storm = c("Alberto", "Alex", "Allison", "Ana", "Arlene", "Arthur"),
                     wind = c(110,45,65,40,50,45),
                     pressure = c(1007,1009,1005,1013,1010,1010),
                     date = as.Date(c("2000-08-03", "1998-07-27", "1995-06-03", "1997-06-30", "1999-06-11", "1996-06-17")))
storms
# songs-data
songs <- dplyr::data_frame(song = c("Across the Universe", "Come Together", "Hello, Goodbye", "Peggy Sue"),
                    name = c("John", "John", "Paul", "Buddy"))
songs
# artists
artists <- dplyr::data_frame(name = c("George", "John", "Paul", "Ringo"),
                      plays = c("sitar", "guitar", "bass", "drums"))
artists

5 Säännölliset lausekkeet eli regular expressions

library(tidyverse)
## ------------------------------------------------------------------------
str(chickwts)
summary(chickwts)
as_tibble(chickwts)

## ------------------------------------------------------------------------
head(chickwts, 30)

## ------------------------------------------------------------------------
chickwts[chickwts$feed == "horsebean",]

## ------------------------------------------------------------------------
chickwts[chickwts$feed %in% c("horsebean", "soybean"),]

## ------------------------------------------------------------------------
beans <- c("soybean", "castor bean", "lentil", "wheat", "beanie baby", "horsebean", "pinto bean", "potato")
grep("bean", beans)
grep("bean", beans, value=TRUE)

## ------------------------------------------------------------------------
grep("bean$", beans, value=TRUE)

## ------------------------------------------------------------------------
grepl("bean$", beans)
chickwts[grepl("bean$", chickwts$feed),]

## ---- echo=FALSE---------------------------------------------------------
sws <- structure(list(geographicAreaM49 = c("230", "230", "230", "230", 
"230", "230"), timePointYears = c("2013", "2013", "2013", "2013", 
"2013", "2014"), measuredElement = c("5320", "53200", "53201", 
"5510", "55100", "5320"), Value_measuredItemCPC_02111 = c(NA_real_, 
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_), flagObservationStatus_measuredItemCPC_02111 = c(NA_character_, 
NA_character_, NA_character_, NA_character_, NA_character_, NA_character_
), flagMethod_measuredItemCPC_02111 = c(NA_character_, NA_character_, 
NA_character_, NA_character_, NA_character_, NA_character_), 
    Value_measuredItemCPC_21111.01 = c(0, 0, 0, 0, 0, 0), flagObservationStatus_measuredItemCPC_21111.01 = c("M", 
    "M", "M", "M", "M", "M"), flagMethod_measuredItemCPC_21111.01 = c("u", 
    "u", "u", "u", "u", "u")), .Names = c("geographicAreaM49", 
"timePointYears", "measuredElement", "Value_measuredItemCPC_02111", 
"flagObservationStatus_measuredItemCPC_02111", "flagMethod_measuredItemCPC_02111", 
"Value_measuredItemCPC_21111.01", "flagObservationStatus_measuredItemCPC_21111.01", 
"flagMethod_measuredItemCPC_21111.01"), class = "data.frame", row.names = c(NA, 
-6L))

## ------------------------------------------------------------------------
names(sws)

## ------------------------------------------------------------------------
grep("^Value_", names(sws), value=TRUE)

## ---- echo=FALSE---------------------------------------------------------
makenoise <- function(n, selection = letters, length = 5){
  apply(replicate(n, sample(c(selection, ""), length, replace=TRUE, prob=c(rep(0.7/length(selection), length(selection)), .3))), 2, paste0, collapse="")
}
n <- 10
noisystring <- paste0(makenoise(n), sample(1990:2015, n, rep=T), makenoise(n))

## ------------------------------------------------------------------------
noisystring

## ------------------------------------------------------------------------
gsub("[a-zA-Z]", "", noisystring)

## ---- echo=FALSE---------------------------------------------------------
n <- 10
selection <- c(letters, "&", "_")
noisystring2 <- paste0(makenoise(n, selection), sample(1990:2015, n, rep=T), makenoise(n, selection))

## ------------------------------------------------------------------------
noisystring2

## ------------------------------------------------------------------------
gsub("[^0-9]", "", noisystring2)

noisydata <- data_frame(noisystring,noisystring2)
noisydata$noisydata_numbers <- gsub("[^0-9]", "", noisydata$noisystring2)
noisydata$noisydata_letters <- gsub("[0-9]", "", noisydata$noisystring2)

2016 Markus Kainu.

Creative Commons -lisenssi
Tämä teos on lisensoitu Creative Commons Nimeä 4.0 Kansainvälinen -lisenssillä.

Tämä sivusto on tehty R:ssä Rmarkdown-paketin uusimmassa kehitysversion uudella render_site()`-funktiolla, jonka tekee staattisten responsiivisten verkkosivujen tekemisen helpoksi. Katso ohjeet: