Kapitel 3 Datamanipulering med dplyr
Det sägs ofta att en Data Scientist ägnar 80% av sin tid till att manipulera data så att den går att visualisera och modellera. Därför är det klokt att välja en metod och ett paket som underlättar det arbetet för dig.
I den här introduktionen kommer vi att fokusera på att använda paketet dplyr
för att göra datamanipuleringar. dplyr
är ett av de mest populära paketen i R och ger dig en bred verktygslåda för att manipulera data. dplyr
ingår också i ett samlingspaket tidyverse
och samlar flertalet paket för datamanipulering, visualisering och modellering.
dplyr
har ett antal verb för att göra manipuleringar:
filter()
där du väljer observationer baserat på deras värdenarrange()
som ändrar ordningen på raderselect()
för att välja variabler baserat på deras namnmutate()
för att skapa nya variabler baserat på funktionersummarise()
för att summera många värden till ett värde
Samtliga av dessa verb kan användas i kombination med funktionen group_by()
som innebär att du utför verben på flera grupper.
Alla verb i dplyr
är konsekventa. Det första argumentet är din data och i det andra argumentet specificerar du vad du vill göra med din data. Resultatet är alltid en ny data.frame.
3.1 Filter
Med filter kan du enkelt filtrera din data baserat på villkor.
Dessa villkor uttrycks med hjälp av relationsoperatorer
och logical operators
.
I R är dessa:
Relationsoperator | Symbol i R |
---|---|
och (and) | & |
eller(or) | | |
icke(not) | ! |
Logical Operators | Symbol i R |
---|---|
lika | == |
inte lika | != |
större än eller lika | >= |
mindre än eller lika | <= |
större än | > |
mindre än | < |
finns i | %in% |
Dessa kan du använda i filter()
.
PS: Det vanligaste misstaget i början av din R-karriär är att skriva =
istället för ==
.
Så här använder du operatorerna:
Hitta alla flyg som kom fram 08:30 under februari
## # A tibble: 9 x 19
## year month day dep_time sched_dep_time dep_delay arr_time
## <int> <int> <int> <int> <int> <dbl> <int>
## 1 2013 2 2 656 700 -4 830
## 2 2013 2 4 652 600 52 830
## 3 2013 2 6 629 630 -1 830
## 4 2013 2 13 633 636 -3 830
## 5 2013 2 18 717 700 17 830
## 6 2013 2 24 557 600 -3 830
## 7 2013 2 25 532 540 -8 830
## 8 2013 2 26 615 615 0 830
## 9 2013 2 28 621 630 -9 830
## # … with 12 more variables: sched_arr_time <int>, arr_delay <dbl>,
## # carrier <chr>, flight <int>, tailnum <chr>, origin <chr>, dest <chr>,
## # air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>,
## # time_hour <dttm>
Hitta alla flygbolag som finns i c("UA", "DL")
i februari eller mars och som inte var försenade.
## # A tibble: 10,346 x 19
## year month day dep_time sched_dep_time dep_delay arr_time
## <int> <int> <int> <int> <int> <dbl> <int>
## 1 2013 2 1 520 525 -5 816
## 2 2013 2 1 527 530 -3 837
## 3 2013 2 1 554 601 -7 920
## 4 2013 2 1 558 600 -2 738
## 5 2013 2 1 559 600 -1 923
## 6 2013 2 1 600 600 0 833
## 7 2013 2 1 601 608 -7 703
## 8 2013 2 1 601 608 -7 723
## 9 2013 2 1 604 610 -6 752
## 10 2013 2 1 608 615 -7 837
## # … with 10,336 more rows, and 12 more variables: sched_arr_time <int>,
## # arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>,
## # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## # minute <dbl>, time_hour <dttm>
3.1.1 Övning
Hur många plan…
- var försenade mer än 1 timme?
- skulle till Boston (“BOS”)
- lämnade JFK och var försenade
- lämnade JFK på julafton
- var försenade, men inte kom fram försent
- flög United Airlines (UA) eller American Airlines?
3.2 Arrange
arrange()
kastar om ordningen på dina rader enligt en av dig vald variabel. Exempelvis kanske vi vill sortera data på försenade avgångar dep_delay
.
## # A tibble: 336,776 x 19
## year month day dep_time sched_dep_time dep_delay arr_time
## <int> <int> <int> <int> <int> <dbl> <int>
## 1 2013 12 7 2040 2123 -43 40
## 2 2013 2 3 2022 2055 -33 2240
## 3 2013 11 10 1408 1440 -32 1549
## 4 2013 1 11 1900 1930 -30 2233
## 5 2013 1 29 1703 1730 -27 1947
## 6 2013 8 9 729 755 -26 1002
## 7 2013 10 23 1907 1932 -25 2143
## 8 2013 3 30 2030 2055 -25 2213
## 9 2013 3 2 1431 1455 -24 1601
## 10 2013 5 5 934 958 -24 1225
## # … with 336,766 more rows, and 12 more variables: sched_arr_time <int>,
## # arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>,
## # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## # minute <dbl>, time_hour <dttm>
arrange()
sorterar per default på sjunkande värde (ascending). Vill du sortera på stigande värde (descending) sätter du desc()
runt din variabel.
## # A tibble: 336,776 x 19
## year month day dep_time sched_dep_time dep_delay arr_time
## <int> <int> <int> <int> <int> <dbl> <int>
## 1 2013 1 9 641 900 1301 1242
## 2 2013 6 15 1432 1935 1137 1607
## 3 2013 1 10 1121 1635 1126 1239
## 4 2013 9 20 1139 1845 1014 1457
## 5 2013 7 22 845 1600 1005 1044
## 6 2013 4 10 1100 1900 960 1342
## 7 2013 3 17 2321 810 911 135
## 8 2013 6 27 959 1900 899 1236
## 9 2013 7 22 2257 759 898 121
## 10 2013 12 5 756 1700 896 1058
## # … with 336,766 more rows, and 12 more variables: sched_arr_time <int>,
## # arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>,
## # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## # minute <dbl>, time_hour <dttm>
3.2.1 Övning
Hitta det flyg som…
- flög längst
- var mest försenat (när det kom fram)
3.3 Select
Medan arrange()
kastar om raderna så kastar select()
om kolumnerna. Men mest används den för att välja ut kolumner av intresse.
## # A tibble: 336,776 x 2
## dep_delay carrier
## <dbl> <chr>
## 1 2 UA
## 2 4 UA
## 3 2 AA
## 4 -1 B6
## 5 -6 DL
## 6 -4 UA
## 7 -5 B6
## 8 -3 EV
## 9 -3 B6
## 10 -2 AA
## # … with 336,766 more rows
Om du av något skäl vill flytta en kolumn till början kan du skriva:
## # A tibble: 336,776 x 19
## carrier year month day dep_time sched_dep_time dep_delay arr_time
## <chr> <int> <int> <int> <int> <int> <dbl> <int>
## 1 UA 2013 1 1 517 515 2 830
## 2 UA 2013 1 1 533 529 4 850
## 3 AA 2013 1 1 542 540 2 923
## 4 B6 2013 1 1 544 545 -1 1004
## 5 DL 2013 1 1 554 600 -6 812
## 6 UA 2013 1 1 554 558 -4 740
## 7 B6 2013 1 1 555 600 -5 913
## 8 EV 2013 1 1 557 600 -3 709
## 9 B6 2013 1 1 557 600 -3 838
## 10 AA 2013 1 1 558 600 -2 753
## # … with 336,766 more rows, and 11 more variables: sched_arr_time <int>,
## # arr_delay <dbl>, flight <int>, tailnum <chr>, origin <chr>,
## # dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>,
## # time_hour <dttm>
Du kan även välja alla kolumner mellan två kolumner:
## # A tibble: 336,776 x 3
## year month day
## <int> <int> <int>
## 1 2013 1 1
## 2 2013 1 1
## 3 2013 1 1
## 4 2013 1 1
## 5 2013 1 1
## 6 2013 1 1
## 7 2013 1 1
## 8 2013 1 1
## 9 2013 1 1
## 10 2013 1 1
## # … with 336,766 more rows
Genom att sätta ett minus framför variabelnamnet exkluderar du variabeln.
## # A tibble: 336,776 x 18
## month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <dbl> <int> <int>
## 1 1 1 517 515 2 830 819
## 2 1 1 533 529 4 850 830
## 3 1 1 542 540 2 923 850
## 4 1 1 544 545 -1 1004 1022
## 5 1 1 554 600 -6 812 837
## 6 1 1 554 558 -4 740 728
## 7 1 1 555 600 -5 913 854
## 8 1 1 557 600 -3 709 723
## 9 1 1 557 600 -3 838 846
## 10 1 1 558 600 -2 753 745
## # … with 336,766 more rows, and 11 more variables: arr_delay <dbl>,
## # carrier <chr>, flight <int>, tailnum <chr>, origin <chr>, dest <chr>,
## # air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>,
## # time_hour <dttm>
3.3.0.1 select() plus hjälpfunktioner
select()
kommer med ett antal hjälpfunktioner:
starts_with("asd")
ends_with("air")
contains("flyg")
matches("asd")
num_range("flyg", 1:10)
De används för att identifiera kolumner baserat på text.
Exempelvis kan du hitta alla delay-kolumner med contains
.
## # A tibble: 336,776 x 2
## dep_delay arr_delay
## <dbl> <dbl>
## 1 2 11
## 2 4 20
## 3 2 33
## 4 -1 -18
## 5 -6 -25
## 6 -4 12
## 7 -5 19
## 8 -3 -14
## 9 -3 -8
## 10 -2 8
## # … with 336,766 more rows
3.3.0.2 rename()
En annan nyttig funktion är rename()
som kort och gott döper om variabler.
Formeln är rename(data, ny_variabel = gammal_variabel)
3.3.1 Övning
- Som innehåller “dep”
- Som börjar med “dep”
- Döp om
dep_delay
tillförsenad_avgång
3.4 Mutate
mutate()
används för att skapa nya variabler.
Exempelvis kan vi räkna ut hur mycket tid man vunnit om exempelvis flyget landar tidigare än avsett.
## # A tibble: 336,776 x 20
## year month day dep_time sched_dep_time dep_delay arr_time
## <int> <int> <int> <int> <int> <dbl> <int>
## 1 2013 1 1 517 515 2 830
## 2 2013 1 1 533 529 4 850
## 3 2013 1 1 542 540 2 923
## 4 2013 1 1 544 545 -1 1004
## 5 2013 1 1 554 600 -6 812
## 6 2013 1 1 554 558 -4 740
## 7 2013 1 1 555 600 -5 913
## 8 2013 1 1 557 600 -3 709
## 9 2013 1 1 557 600 -3 838
## 10 2013 1 1 558 600 -2 753
## # … with 336,766 more rows, and 13 more variables: sched_arr_time <int>,
## # arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>,
## # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## # minute <dbl>, time_hour <dttm>, beer_time <dbl>
I mutate()
kan du även använda funktioner såsom mean()
.
## # A tibble: 336,776 x 20
## year month day dep_time sched_dep_time dep_delay arr_time
## <int> <int> <int> <int> <int> <dbl> <int>
## 1 2013 1 1 517 515 2 830
## 2 2013 1 1 533 529 4 850
## 3 2013 1 1 542 540 2 923
## 4 2013 1 1 544 545 -1 1004
## 5 2013 1 1 554 600 -6 812
## 6 2013 1 1 554 558 -4 740
## 7 2013 1 1 555 600 -5 913
## 8 2013 1 1 557 600 -3 709
## 9 2013 1 1 557 600 -3 838
## 10 2013 1 1 558 600 -2 753
## # … with 336,766 more rows, and 13 more variables: sched_arr_time <int>,
## # arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>,
## # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## # minute <dbl>, time_hour <dttm>, mean_delay <dbl>
3.4.1 if_else()
En vanlig funktion i databearbetning är ifelse-satser.
I R gör du det enklast med funktionen if_else()
från dplyr
. Det finns även en inbyggd funktion som heter ifelse()
som mestadels fungerar bra men den från dplyr
är något mer stabil.
Du kan använda den i mutate:
## # A tibble: 336,776 x 20
## year month day dep_time sched_dep_time dep_delay arr_time
## <int> <int> <int> <int> <int> <dbl> <int>
## 1 2013 1 1 517 515 2 830
## 2 2013 1 1 533 529 4 850
## 3 2013 1 1 542 540 2 923
## 4 2013 1 1 544 545 -1 1004
## 5 2013 1 1 554 600 -6 812
## 6 2013 1 1 554 558 -4 740
## 7 2013 1 1 555 600 -5 913
## 8 2013 1 1 557 600 -3 709
## 9 2013 1 1 557 600 -3 838
## 10 2013 1 1 558 600 -2 753
## # … with 336,766 more rows, and 13 more variables: sched_arr_time <int>,
## # arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>,
## # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## # minute <dbl>, time_hour <dttm>, försenad <chr>
Ibland vill man göra flera stycken if_else()
i samma, exempelvis om man vill dela upp en variabel i flera kategorier beroende på ett logiskt villkor. För att göra det kan du använda funktionen case_when()
.
mutate(flights, försenad_kat = case_when(
dep_delay < 0 ~ "före tid",
dep_delay == 0 ~ "i tid",
dep_delay > 0 ~ "försenad"))
## # A tibble: 336,776 x 20
## year month day dep_time sched_dep_time dep_delay arr_time
## <int> <int> <int> <int> <int> <dbl> <int>
## 1 2013 1 1 517 515 2 830
## 2 2013 1 1 533 529 4 850
## 3 2013 1 1 542 540 2 923
## 4 2013 1 1 544 545 -1 1004
## 5 2013 1 1 554 600 -6 812
## 6 2013 1 1 554 558 -4 740
## 7 2013 1 1 555 600 -5 913
## 8 2013 1 1 557 600 -3 709
## 9 2013 1 1 557 600 -3 838
## 10 2013 1 1 558 600 -2 753
## # … with 336,766 more rows, and 13 more variables: sched_arr_time <int>,
## # arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>,
## # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## # minute <dbl>, time_hour <dttm>, försenad_kat <chr>
3.4.2 Andra funktioner
I mutate()
kan du använda de allra flesta funktionerna i R. Här är exempel på några funktioner som kan vara nyttiga i databearbetning:
- Funktioner för att ranka variabler:
rank()
,min_rank()
,dense_rank()
,percent_rank()
- För att logaritmiska funktioner:
log()
,log10()
- För kumulativa beräkningar:
cumsum()
,cummean()
- För att bara generera radnummer:
row_number()
- För att ta observation innan eller efter:
lead()
ochlag()
- För skapa variabler baserat på värde i andra variabler
if_else()
ochcase_when()
3.4.3 Övningar
- Skapa en variabel som innehåller den totala förseningen
- Rangordna flygens distans. Hur hanterar du fall där distansen är lika lång?
- Skapa en variabel som anger om flyget går på våren, hösten, vintern eller sommaren.
3.5 Summarise
Ofta vill man summera variabler för att få ut intressant information. Exempelvis vill vi här kanske veta en rad medelvärden.
## # A tibble: 1 x 1
## mean_dist
## <dbl>
## 1 1040.
## # A tibble: 1 x 1
## sum_dist
## <dbl>
## 1 350217607
## # A tibble: 1 x 1
## count
## <int>
## 1 336776
Men dessa värden är inte så intressanta i sig, utan vi vill kunna göra jämförelse. Då använder vi group_by()
.
group_by_flights <- group_by(flights, carrier)
summarise(group_by_flights,
mean_air_time = mean(air_time, na.rm = T),
mean_dep_delay = mean(dep_delay, na.rm = T),
mean_arr_delay = mean(arr_delay, na.rm = T))
## # A tibble: 16 x 4
## carrier mean_air_time mean_dep_delay mean_arr_delay
## <chr> <dbl> <dbl> <dbl>
## 1 9E 86.8 16.7 7.38
## 2 AA 189. 8.59 0.364
## 3 AS 326. 5.80 -9.93
## 4 B6 151. 13.0 9.46
## 5 DL 174. 9.26 1.64
## 6 EV 90.1 20.0 15.8
## 7 F9 230. 20.2 21.9
## 8 FL 101. 18.7 20.1
## 9 HA 623. 4.90 -6.92
## 10 MQ 91.2 10.6 10.8
## 11 OO 83.5 12.6 11.9
## 12 UA 212. 12.1 3.56
## 13 US 88.6 3.78 2.13
## 14 VX 337. 12.9 1.76
## 15 WN 148. 17.7 9.65
## 16 YV 65.7 19.0 15.6
I summarise()
kan du använda en rad olika funktioner såsom sum()
för summeringar, median()
etc.
3.5.0.1 Övningar
- Vilken flygplats har högst medelvärde förförseningar från flygplatsen?
- Vilken flygplats tar emot minst flyg?
3.5.0.2 Väv ihop verben med %>%
Med %>%
(som kallas för pipe
and kan uttalas som and then
) kan länka ihop flera uttryck i R. Det gör framför allt din kod mer lättläst.
Med %>%
kan du exempelvis först filtrera, sen gruppera och till sist summera, allt i samma uttryck.
flights %>%
filter(dep_delay < 60) %>%
group_by(carrier) %>%
summarise(mean_dep_delay = mean(dep_delay, na.rm = T))
## # A tibble: 16 x 2
## carrier mean_dep_delay
## <chr> <dbl>
## 1 9E 2.96
## 2 AA 0.890
## 3 AS -0.719
## 4 B6 3.26
## 5 DL 1.76
## 6 EV 4.65
## 7 F9 5.09
## 8 FL 4.72
## 9 HA -2.47
## 10 MQ 1.48
## 11 OO -2.88
## 12 UA 4.33
## 13 US -0.744
## 14 VX 2.70
## 15 WN 6.60
## 16 YV 2.25
Du läser alltså:
Första tar vi flights
and then
filtrerar vi på dep_delay
and then
grupperar vi på carrier
and then
räknar vi ut medelvärde på dep_delay
.
Vilket är mycket mer lättläst än motsvarigheten med parenteser:
3.5.0.3 count()
Du kan i summarise()
räkna antalet observationer med funktionen n()
.
## # A tibble: 16 x 2
## carrier count
## <chr> <int>
## 1 9E 18460
## 2 AA 32729
## 3 AS 714
## 4 B6 54635
## 5 DL 48110
## 6 EV 54173
## 7 F9 685
## 8 FL 3260
## 9 HA 342
## 10 MQ 26397
## 11 OO 32
## 12 UA 58665
## 13 US 20536
## 14 VX 5162
## 15 WN 12275
## 16 YV 601
Men istället för att göra det här kan du använda funktionen count()
## # A tibble: 16 x 2
## # Groups: carrier [16]
## carrier n
## <chr> <int>
## 1 9E 18460
## 2 AA 32729
## 3 AS 714
## 4 B6 54635
## 5 DL 48110
## 6 EV 54173
## 7 F9 685
## 8 FL 3260
## 9 HA 342
## 10 MQ 26397
## 11 OO 32
## 12 UA 58665
## 13 US 20536
## 14 VX 5162
## 15 WN 12275
## 16 YV 601
3.6 sample_n()
Att göra slumpmässiga urval är en vanlig arbetsuppgift för en data scientist. Det gör du enkelt med sample_n()
från dplyr
.
Om du vill ta ett slumpmässigt urval om 10 från exempelvis flights
gör du bara:
## # A tibble: 10 x 19
## year month day dep_time sched_dep_time dep_delay arr_time
## <int> <int> <int> <int> <int> <dbl> <int>
## 1 2013 4 19 1858 1825 33 2307
## 2 2013 7 27 1522 1520 2 1736
## 3 2013 7 19 1053 1100 -7 1328
## 4 2013 9 17 826 830 -4 1020
## 5 2013 8 6 1716 1720 -4 1850
## 6 2013 11 3 1725 1730 -5 2013
## 7 2013 3 21 1810 1815 -5 1948
## 8 2013 9 17 752 800 -8 912
## 9 2013 7 12 1651 1655 -4 1821
## 10 2013 1 20 1257 1300 -3 1510
## # … with 12 more variables: sched_arr_time <int>, arr_delay <dbl>,
## # carrier <chr>, flight <int>, tailnum <chr>, origin <chr>, dest <chr>,
## # air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>,
## # time_hour <dttm>
Om du istället vill ta ett urval som baseras på procent kan du använda sample_frac
, här för 0.01%
## # A tibble: 337 x 19
## year month day dep_time sched_dep_time dep_delay arr_time
## <int> <int> <int> <int> <int> <dbl> <int>
## 1 2013 4 5 2036 2035 1 2343
## 2 2013 4 21 846 850 -4 1252
## 3 2013 2 18 626 630 -4 812
## 4 2013 6 2 1445 1445 0 1734
## 5 2013 7 9 1136 1125 11 1359
## 6 2013 2 25 532 530 2 854
## 7 2013 12 31 1713 1650 23 1935
## 8 2013 12 15 NA 755 NA NA
## 9 2013 9 11 1227 1159 28 1512
## 10 2013 1 18 1500 1457 3 1817
## # … with 327 more rows, and 12 more variables: sched_arr_time <int>,
## # arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>,
## # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## # minute <dbl>, time_hour <dttm>
3.6.1 Övning
- Vilken månad ska du flyga under för att undvika förseningar?
- Vilken tid ska du flyga för att undvika förseningar?
- Hitta det flygbolag som flyger till flest destinationer, rangordna flygbolagen baserat på den informationen.