Datan tuominen
# asetetaan options
options(scipen=999)
# TUODAAN DATAT
# -----------------------------------------------------------------
# Osallistujadata limesurveysta
# devtools::install_github("cloudyr/limer")
library(limer)
options(lime_api = "http://muuankarski.org/limesurvey/index.php/admin/remotecontrol")
options(lime_username = '###')
passwd <- '###'
options(lime_password = passwd)
get_session_key()
osallistujat <- get_responses(129581, sLanguageCode = "fi") # Get results from survey
release_session_key()
# Sukunimidata avoindata.fi:stä
dir.create("./data")
download.file("https://www.avoindata.fi/dataset/57282ad6-3ab1-48fb-983a-8aba5ff8d29a/resource/ef50d7ca-da3c-4d50-90e2-f985b8a7a099/download/HNimidatan-avaaminen2016JulkaistavatSukunimet2016.csv",
destfile="./data/Sukunimet2016.csv")
sukunimet <- read.csv("./data/Sukunimet2016.csv",
stringsAsFactors = FALSE,
fileEncoding = "Latin1",
sep=";",
header = T)
head(sukunimet, 10)
summary(sukunimet)
str(sukunimet)
# Naisten etunimet
download.file("https://www.avoindata.fi/dataset/57282ad6-3ab1-48fb-983a-8aba5ff8d29a/resource/cc4dc77d-a80f-423f-b4ef-07394943d7c3/download/HNimidatan-avaaminen2016JulkaistavatNaisetkaikkietunimet2016.csv", destfile="./data/Naisetkaikkietunimet2016.csv")
naiset <- read.csv("./data/Naisetkaikkietunimet2016.csv",
stringsAsFactors = FALSE,
fileEncoding = "Latin1",
sep=";",
header = T)
head(naiset, 10)
summary(naiset)
str(naiset)
# Miesten etunimet
download.file("https://www.avoindata.fi/dataset/57282ad6-3ab1-48fb-983a-8aba5ff8d29a/resource/53667ad0-538c-4686-86e0-361c129dcd95/download/HNimidatan-avaaminen2016JulkaistavatMiehetkaikkietunimet2016.csv", destfile="./data/Miehetkaikkietunimet2016.csv")
miehet <- read.csv("./data/Miehetkaikkietunimet2016.csv",
stringsAsFactors = FALSE,
fileEncoding = "Latin1",
sep=";",
header = T)
head(miehet, 10)
summary(miehet)
str(miehet)
Siivoa
# Siivotaan datat
library(dplyr)
suku <- sukunimet %>%
mutate(n_vaesto = as.integer(gsub("[^0-9]", "", YHTEENSÄ))) %>%
select(SUKUNIMI,n_vaesto) %>%
rename(sukunimi = SUKUNIMI)
m <- miehet %>%
mutate(n_vaesto = as.integer(gsub("[^0-9]", "", YHTEENSÄ))) %>%
select(NIMI,n_vaesto) %>%
mutate(supu = "miehet") %>%
rename(nimi = NIMI)
n <- naiset %>%
mutate(n_vaesto = as.integer(gsub("[^0-9]", "", YHTEENSÄ))) %>%
select(NIMI,n_vaesto) %>%
mutate(supu = "naiset") %>%
rename(nimi = NIMI)
os <- osallistujat %>%
select(etunimi,sukunimi) %>%
group_by(etunimi) %>%
mutate(n_osallistujat=n()) %>%
rename(nimi = etunimi) %>%
ungroup()
Muokkaa
# Muokkaa
etu <- rbind(m,n)
etu2 <- left_join(etu,os)
suku2 <- left_join(suku,os)
## tehdään rnk-muuttujat suositummuuden mukaan!
etu2 <- etu2 %>%
arrange(-n_vaesto) %>%
filter(!duplicated(nimi)) %>%
mutate(rnk = row_number())
suku2 <- suku2 %>%
arrange(-n_vaesto) %>%
filter(!duplicated(sukunimi)) %>%
mutate(rnk = row_number())
Visualisoi
library(ggplot2)
# etunimet
plot_df <- etu2
plot_df <- plot_df[!is.na(plot_df$n_osallistujat),]
p <- ggplot(data=plot_df, aes(x=factor(rnk)))
p <- p + geom_bar(aes(y=n_vaesto,fill=supu), stat="identity",position="dodge")
p <- p + scale_y_log10(breaks=c(10,100,1000, 10000, 50000))
p <- p + geom_text(data=plot_df %>% filter(!is.na(n_osallistujat)),nudge_y = -.1,
aes(x=factor(rnk),y=n_vaesto,label=paste0(rnk,". ",nimi," - ",n_vaesto)),
size=4,hjust=1, color="white", angle=90)
p <- p + theme_light()
p <- p + theme(axis.text.x=element_blank())
p <- p + theme(axis.title=element_blank())
p <- p + theme(axis.ticks=element_blank())
p <- p + theme(legend.position="top")
p
# sukunimet
plot_df <- suku2
plot_df <- plot_df[!is.na(plot_df$n_osallistujat),]
p <- ggplot(data=plot_df, aes(x=factor(rnk)))
p <- p + geom_bar(aes(y=n_vaesto), stat="identity",position="dodge")
p <- p + scale_y_log10(breaks=c(10,100,1000, 10000))
p <- p + geom_text(data=plot_df %>% filter(!is.na(n_osallistujat)),nudge_y = -.1,
aes(x=factor(rnk),y=n_vaesto,label=paste0(rnk,". ",sukunimi," - ",n_vaesto)),
size=4,hjust=1, color="white", angle=90)
p <- p + theme_light()
p <- p + theme(axis.text.x=element_blank())
p <- p + theme(axis.title=element_blank())
p <- p + theme(axis.ticks=element_blank())
p
Kommunikoi
Ctrl+Shift+k
#' ---
#' title: Nimianalyysi
#' author: Etunimi Sukunimi
#' date: "`r Sys.time()`"
#' output:
#' html_document:
#' toc: true
#' toc_float: true
#' number_sections: yes
#' code_folding: hide
#' theme: united
#' ---
To understand computations in R, two slogans are helpful:
John Chambers Creator of the S programming language, and core member of the R programming language project.
- Everything that exists is an object.
- Everything that happens is a function call.“
Eli R:n toiminnan ymmärtämisessä on tärkeää muistaa kaksi asiaa:
Seuraavat kaksi tapaa ovat identtiset, mutta käytän ensimmäistä sillä ´=ja
<-` eivät ole kaikissa toimenpiteissä yhtäläisiä operaattoreita.
objekti <- objektin_arvo
objekti = objektin_arvo
#
getwd()
#
setwd()
Rstudiota ja sen projects-ominaisuutta käytettäessä työhakemiston on oletuksena aina ko. projektin hakemisto.
100 * (0.05 + 0.05)
# [1] 10
sqrt(10+6)
# [1] 4
Everything that exists is an object.
vektorien luominen manuaalisesti
# muneerinen vektori jonka pituus on 1 ja arvo 100
sata <- 100
sata
# [1] 100
is(sata)
# [1] "numeric" "vector"
# character vektori jonka pituus on 1 ja arvo "sata"
sata_tekstina <- "sata"
sata_tekstina
# [1] "sata"
is(sata_tekstina)
# [1] "character" "vector" "data.frameRowLabels" "SuperClassMethod"
# Luodaan kaksi 7 elementin pituista vektoria, joista toinen on numeerinen ja toinen character
nimi <- c("Juhani","Tuomas","Aapo","Simeoni","Timo","Lauri","Eero")
ika <- c(25,23,23,22,20,20,17)
typeof(nimi)
# "character"
typeof(ika)
# "double"
length(ika)
faktorit
nimi <- c("Juhani","Tuomas","Aapo","Simeoni","Timo","Lauri","Eero")
typeof(nimi)
nimi <- as.factor(nimi)
typeof(nimi)
nimi <- factor(nimi, levels=c("Juhani","Tuomas","Aapo","Simeoni","Timo","Lauri","Eero"))
library(forcats) # uusi paketti faktoreiden kanssa työskentelyyn - palataan myöhemmin visualisoinneissa tähän
data.frame luominen manuaalisesti
# Olemassaolevista vektoreista
nimi <- c("Juhani","Tuomas","Aapo","Simeoni","Timo","Lauri","Eero")
ika <- c(25,23,23,22,20,20,17)
d2 <- data.frame(
nimi,
ika,
stringsAsFactors = FALSE
)
# Vektori
d1 <- data.frame(
nimi = c("Juhani","Tuomas","Aapo","Simeoni","Timo","Lauri","Eero"),
ika = c(25,23,23,22,20,20,17),
stringsAsFactors = FALSE
)
d3 <- read.table(textConnection("
nimi ika
Juhani 25
Tuomas 23
Aapo 23
Simeoni 22
Timo 20
Lauri 20
Eero 1
"), header=TRUE,
stringsAsFactors=FALSE)
Kaava uusien objektien (tällä kurssilla datojen) luomiseen on objekti <- arvo
Everything that happens is a function call
vektori <- c(1,2,3,4,5,6,7,8)
ka <- mean(vektori)
ka
# [1] 4.5
is(mean)
# [1] "function" "OptionalFunction" "PossibleMethod"
sum(vektori)
# [1] 36
Koodia kirjoitetaan ensisijaisesti tietokoneelle, mutta sen pitää olla ymmärrettävää myös ihmisille. R-ympäristössä on erilaisia tapoja kirjoittaa komentoja, ja tällä kurssilla pyrin käyttämään paljon ns. ketjutusta (piping ie. pipeline). R:ään tämän ketjutuksen tarjoaa magrittr-paketti. Alla yritetty konkretisoida erilaisia tapoja kirjoittaa prosessia, tässä tapauksessa parsakaalin valmistusta.
# 1) Yksi operaatio per rivi
parsakaalta <- buy(what="broccoli")
keitettyä_parsakaalta <- cook(parsakaali, level = "medium")
tulista_keitettyä_parsakaalta <- add_spices(keitettyä_parsakaalta, type = "chili")
tulista_keitettyä_parsakaalta_voilla <- add_dressing(tulista_keitettyä_parsakaalta, type = "butter")
# 2) operaatiot sisäkkäin yhdellä rivillä
tulista_keitettyä_parsakaalta_voilla <- add_dressing(add_spices(cook(buy(what="broccoli"), level = "medium"), type = "chili"), type = "butter")
# 3) Operaatiot ketjutettuina
buy(what="broccoli") %>%
cook(level = "medium") %>%
add_spices(type = "chili") %>%
add_dressing(type = "butter") -> tulista_keitettyä_parsakaalta_voilla
# luo kansio "aineisto" nykyiseen työhakenmistoon
dir.create("./aineisto")
# luo uusi tekstitiedosto "teksti.txt" nykyiseen työhakemistoon
file.create("./teksti.txt")
# avaa äsken luotu tekstitiedosto muokattavaksi
file.edit("./teksti.txt")
# listaa työhakemistossa ja sen alahakemistoissa olevat tiedostot, joiden nimessä on sana "luento"
list.files(path = "./", all.files = TRUE, full.names = TRUE, recursive = TRUE, pattern = "luento")
# listaa kaikki työhakemiston alahakemistot ja niiden alahakemistot
list.dirs(path = "./", recursive = TRUE, full.names = TRUE)
# kopioi tiedosto teksti.txt kansioon aineisto
file.copy(from = "./teksti.txt", to = "./aineisto")
# poista kaikki tiedostot työhakemistosta, joilla pääte ".txt"
file.remove(list.files(path = "./", pattern = ".txt$"))
# tiedostojen lataaminen verkosta levylle
download.file(url = "http://siteresources.worldbank.org/INTRES/Resources/469232-1107449512766/allginis_2013.xls", destfile = "./allginis_2013.xls")
# pakattujen zip-tiedostojen purkaminen
download.file(url = "http://faostat3.fao.org/faostat-bulkdownloads/Population_E_Europe_1.zip", destfile = "./Population_E_Europe_1.zip")
unzip("./Population_E_Europe_1.zip", exdir = "./zip")
Asentamalla uusia paketteja saat R:ään käyttöön uusia funktioita. Monissa paketeissa mukana tulee myös pieniä datoja funktioiden käytön harjoitteluun. Useimmat paketeista mahdollistavat jonkun laskennallisen operaation tekemisen, yhä useammat tarjoavat toiminnallisuuksia R:stä esim. tietokantojen (eurostat
) tai verkkoteknologioiden (leaflet
) rajapintoihin.
# Asenna keskitetystä pakettihallinnasta CRAN
install.packages("eurostat")
# Ota paketti käyttöön
library(eurostat)
# Asenna kehitysversiot github:sta
library(devtools) # tarvitaan funktio devtools-paketista
install_github("ropengov/eurostat")
Ladattujen pakettien uusia funktioita voi käyttää joko A) lataamalla paketin ja kutsumalla funktiota tai B) kutsumalla pakettia ja funktiota yhtä aikaa. Tämän kurssin materiaaleissa pyrin käyttämään aina vaihtoehtoa B, jotta opiskelijoille olisi selkeämpää milloin käytössä oleva funktio on ns. “ulkoisesta” paketista.
# tapa A
library(eurostat)
d <- get_eurostat(id = "tgs00026")
# tapa B
d <- eurostat::get_eurostat(id = "tgs00026")
Kurssin esimerkeissä tästä eteenpäin näytetään aina kaksi erilaista tapaa toteuttaa sama operaatio, 1) ns. base-R ratkaisu (ilman lisäpaketteja) ja 2) dplyr ratkaisu. Ratkaisut ovat aina peräkkäin ja dplyr
-toteutus on aina merkitty eksplisiittisesti dplyr::funktio_x()
.
Kurssillä pyrimme käyttämään ainoastaan ns. data.frame
luokkaan kuuluvia objekteja. Teknisesti ajateltuna R:ssä data.frame
on vektoreista koostuva lista. Vektorit voivat olla numeerisia, tekstiä tai faktoreita, mutta niiden tulee olla saman pituisia (ks. 7-veljestä demo).
Käytetään dataa mtcars
.
nrow(mtcars) # rivien määrä
ncol(mtcars) # sarakkeiden/muuttujien määrä
dim(mtcars) # molemmat
# Kuusi ensimmäistä riviä
head(mtcars) # tai
mtcars[1:6,] # tai
# dplyr-tapa
dplyr::slice(mtcars, 1:6)
data.frame
vs. tibble
R:llä on jo ikää ja tavanomaisen data.frame
:n oheen on kehitetty vastaavia hieman modernimpia luokkia, kuten data.table
ja tibble
. data.table
on saman nimisen paketin luokka vastaavalle rakenteelle, jolle tehdyt metodit ovat nopeita. Luokka eroaa data.frame
luokasta sen verran, että perusmetodit eivät aina toimi. Mm. siitä syystä tällä kurssilla käytämme rinnakkain datoja luokissa tibble
ja data.frame
.
# tulostetaan data sellaisenaan
mtcars
# tehdään datasta tibble ja tulostetaan
mtcars_tb <- tibble::as_tibble(mtcars)
mtcars_tb
# ladataan ggplot2 ja tarkastellaan dataa diamonds
library(ggplot2)
is(diamonds)
# [1] "tbl_df" "tbl" "data.frame" "list" "oldClass" "vector"
timantit <- as.data.frame(diamonds)
is(timantit)
# "data.frame" "list" "oldClass" "vector"
# mtcars-datassa on autojen merkit rivien niminä (row.names). Tehdään niistä brand-muuttuja
mtcars$brand <- row.names(mtcars)
mtcars <- dplyr::mutate(mtcars, brand=row.names(mtcars)) # dplyr
# valitaan kaikki kuusi sylinteriset autot
mtcars[mtcars$cyl == 6,]
dplyr::filter(mtcars, cyl == 6) # dplyr
# valitaan kaikki alle kuusisylinteriset autot, joissa neljä vaihdetta
mtcars[mtcars$cyl < 6 & mtcars$gear == 4,]
dplyr::filter(mtcars, cyl < 6, gear == 4) # dplyr
# valitaan kaikki F:llä alkavat automerkit
mtcars[grepl("^F", mtcars$brand),]
dplyr::filter(mtcars, grepl("^F", brand)) # dplyr
# valitaan rivit väliltä 10-15
mtcars[10:15,]
dplyr::slice(mtcars, 10:15)
Datan suodattaminen: Sarakkeiden/muuttujien valitseminen
# valitaan muuttujat "cyl", "gear" ja "brand"
mtcars[,c("cyl", "gear","brand")]
dplyr::select(mtcars, cyl, gear, brand) # dplyr
# valitaan kolme ensimmäistä muuttujaa
mtcars[,1:3]
dplyr::select(mtcars, 1:3) # dplyr
# valitaan muuttujat 1,4,6
mtcars[,c(1,4,6)]
dplyr::select(mtcars, c(1,4,6)) # dplyr
Datan suodattaminen: Sekä muuttujien että sarakkeiden valitseminen
# valitaan kaikki alle kuusisylinteriset autot, joissa neljä vaihdetta JA sarakkeet cyl, gear ja brand
mtcars[mtcars$cyl < 6 & mtcars$gear == 4,c("cyl", "gear","brand")]
mtcars %>%
dplyr::filter(cyl < 6, gear == 4) %>%
dplyr::select(cyl, gear, brand)
Muuttujien siivoaminen
# tehdään uusi muuttuja manufacturer, johon valitaan brand-muuttujasta ensimmäinen sana, eli auton valmistajan nimi
mtcars$manufacturer <- stringr::str_extract(string = mtcars$brand, pattern = "[a-öA-Ö]*")
# poistetaan isot alkukirjaimet
mtcars$manufacturer <- tolower(mtcars$manufacturer)
# vaihdetaan kaikkien m-kirjaimella alkavien merkkien ensimmäinen kirjain takaisin isoksi M:ksi
mtcars$manufacturer <- gsub("^m", "M", mtcars$manufacturer)
Uusien muuttujien tekeminen
# lasketaan uusi muuttuja litraa per 100km, muuttujasta mpg
mtcars$ltr_per_km <- 62.13 / mtcars$mpg * 3.79
mtcars
mtcars <- mtcars %>% dplyr::mutate(ltr_per_km = 62.13 / mpg * 3.79)
mtcars
Yksinkertaiset taulukot
# yhden muuttujan luokkien frekvenssit
table(mtcars$manufacturer)
# yhden muuttujan luokkien osuudet
prop.table(table(mtcars$manufacturer))*100
# kahden muuttujan luokkien frekvenssit
table(mtcars$cyl,mtcars$carb)
# kahden muuttujan luokkien frekvenssit
prop.table(table(mtcars$cyl,mtcars$carb))
prop.table(table(mtcars$cyl,mtcars$carb),1)
prop.table(table(mtcars$cyl,mtcars$carb),2)
Ryhmittäiset yhteenvedot
# Kulutuksen keskiarvo sylintereiden mukaan
aggregate(x = mtcars$mpg, by = list(mtcars$cyl), mean)
library(dplyr)
mtcars <- mtcars %>%
dplyr::group_by(cyl) %>%
dplyr::summarise(kulutuksen_ka = mean(mpg),
automallien_maara = n()) # dplyr
datojen yhdistäminen
# Luodaan ryhmittäinen yhteenveto
agg_df <- aggregate(x = mtcars$mpg, by = list(mtcars$cyl), mean)
# yhdistetään mtcars dataan
mtcars <- merge(mtcars,agg_df,by.x="cyl",by.y="Group.1")
agg_df <- mtcars %>%
dplyr::group_by(cyl) %>%
dplyr::summarise(kulutuksen_ka = mean(mpg)) # dplyr
mtcars <- dplyr::left_join(mtcars,agg_df)
# Tai näppärämmin dplyr-paketilla käyttämällä mutate-funktiota
mtcars %>%
dplyr::group_by(cyl) %>%
dplyr::mutate(kulutuksen_ka = mean(mpg)) -> mtcars
Datojen kääntäminen pitkästä leveään muotoon ja takaisin
Perusmuotona tällä kurssilla on aina ns. pitkä muoto (vrt. tidy data)
levea <- read.table(textConnection("
maa 2010 2011 2012 2013 2014
fin 10 11 12 13 14
swe 20 21 22 23 24
nor 30 31 32 33 34
"),stringsAsFactors=FALSE, header = TRUE)
# käännetään pitkäksi tidyr-paketilla
library(tidyr)
tidyr::gather(levea, key = "vuosi", value = "arvo", 2:6)
# lisätään vielä vuosimuuttujat puhdistaminen
tidyr::gather(levea, key = "vuosi", value = "arvo", 2:6) %>%
dplyr::mutate(vuosi = gsub("X", "", vuosi),
vuosi = as.integer(vuosi)) %>%
tibble::as_tibble()
R:n perusasennuksessa tulee joukko datoja mukana, jotka ovat heti käytettävissä. Saat datan kuvauksen kirjoittamalla ?datan_nimi
. Aluksi käytämme dataa ?mtcars
.
?mtcars
head(mtcars)
Samat datat + paljon muuta löytyy Vincent Arel Bundockin ylläpitämältä Rdatasets-sivustolta, josta voimme ladata esimerkiksi saman mtcars
-datan komennolla
d <- read.csv("https://vincentarelbundock.github.io/Rdatasets/csv/datasets/mtcars.csv",
stringsAsFactors = FALSE)
head(d)
Tällä kurssilla rajaamme datalähteet vain joko paikallisella koneella tai verkossa oleviin tiedoistoihin sekä katsomme pikaisesti paria tilastorajapintaa
Data | Paketti | Vaihtoehdot |
---|---|---|
Tekstidatat | readr | base, data.table |
Excel | readxl | gdata, openxlsx, XLConnect, xlsx |
tilasto-ohjelmat | haven | foreign, sas7bdat, readstata13 |
# ladataan ensin zipattu .csv FAO:sta
download.file("http://faostat3.fao.org/faostat-bulkdownloads/Production_Crops_E_Europe_1.zip",
destfile="Production_Crops_E_Europe_1.zip")
unzip("Production_Crops_E_Europe_1.zip")
fao1 <- read.csv("Production_Crops_E_Europe_1.csv",stringsAsFactors = FALSE)
fao2 <- readr::read_csv("Production_Crops_E_Europe_1.csv")
# Luxembourg Income Study -
download.file("http://www.lisdatacenter.org/wp-content/uploads/resources-other-nyt.xlsx", destfile = "./resources-other-nyt.xlsx")
nyt <- readxl::read_excel("resources-other-nyt.xlsx", sheet = 1)
# Kuntaliitto - Alueluokat ja kuntanumerot 2016
download.file("http://www.kunnat.net/fi/tietopankit/tilastot/aluejaot/Documents/Alueluokat%20ja%20kuntanumerot%202016.xlsx", destfile = "kuntanumerot202016.xlsx")
kuntanro <- readxl::read_excel("kuntanumerot202016.xlsx", sheet = 1)
# SPSS
ess <- haven::read_sav("http://courses.markuskainu.fi/utur2016/database/ESS7e02.sav")
# Stata
lits <- haven::read_dta("http://courses.markuskainu.fi/utur2016/database/lits2.dta")
Tilastokeskus
install.packages("pxweb")
tkdata <- pxweb::interactive_pxweb()
THL Sotkanet
install.packages("sotkanet")
sotkanet.indicators <- sotkanet::SotkanetIndicators(type = "table")
knitr::kable(head(sotkanet.indicators))
dat <- sotkanet::GetDataSotkanet(indicators = 10013, years = 1990:2012,
genders = c('female', 'male', 'total'),
region.category = "EUROOPPA", regions = "Suomi")
head(dat) %>% knitr::kable()
Eurostat
install.packages("eurostat")
eurostat::search_eurostat("disposable income") %>%
head() %>%
knitr::kable()
2016 Markus Kainu.
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: