Pakett tidyr on ĂŒks populaarsemaid R keele teeke, tidyverse.
Paketi peamine eesmÀrk on andmete korrastamine.
Habr on juba olemas sellele paketile pĂŒhendatud artikkel, kuid see oli kirjutatud 2015. aastal. Soovin rÀÀkida kĂ”ige olulisematest muudatustest, millest mĂ”ned pĂ€evad tagasi teatas selle looja Hadley Wickham.

SJK: Kas funktsioonid gather() ja spread() muutuvad vananenuks?
Hadley Wickham: Mingil mÀÀral. Me lÔpetame nende funktsioonide kasutamise soovitamise ja nende vigade parandamise, kuid need jÀÀvad paketti senisesse olekusse.
Sisukord
Kui teid huvitab andmeanalĂŒĂŒs, vĂ”ivad teid huvitada minu ja kanalid. Suur osa sisu on pĂŒhendatud R-keelele.
TidyData kontseptsioon
EesmĂ€rk tidyr â aidata teil andmeid korrastada nii-öelda kenasse vormi. Korrastatud andmed on sellised, kus:
- Iga muutuja asub samas veerus.
- Iga tÀhelepanek on rida.
- Iga vÀÀrtus on lahtris.
Korrastatud andmetega on analĂŒĂŒsi viimistlemine oluliselt lihtsam ja mugavam.
Peamised funktsioonid, mis kuuluvad tidyr paketti
Tidyr sisaldab komplekti funktsioone tabelite muutmiseks:
fill()â lahtrite puuduvate vÀÀrtuste tĂ€itmine eelnevate vÀÀrtustega;separate()â jagab ĂŒhe vĂ€lja mitmeks, kasutades eraldajat;unite()â ĂŒhendab mitu vĂ€lja ĂŒheks, vastupidine funktsioonileseparate();pivot_longer()â funktsioon, mis muutab andmeid laiast vormist pikaks;pivot_wider()â funktsioon, mis muutab andmeid pikast vormist laiseks. Vastupidine funktsioonilepivot_longer().gather()minenud â funktsioon, mis muutab andmeid laiast vormist pikaks;spread()minenud â funktsioon, mis muutab andmeid pikast vormist laiseks. Vastupidine funktsioonilegather().
Uus kontseptsioon andmete korrastamisest laiast vormist pika vormi ja vastupidi
Varasema sellise transformatsiooni jaoks kasutati funktsioone gather() ja spread(). Aastate jooksul on nende funktsioonide olemasolu nÀidanud, et enamiku kasutajate, sealhulgas paketi autori jaoks, ei olnud nende funktsioonide ja argumentide nimed piisavalt selged, mis tekitas raskusi nende leidmisel ja mÔistmisel, milline neist funktsioonidest viib andmeraami laiale vÔi pikale vormingule ja vastupidi.
SeetÔttu tidyr lisati
Uued funktsioonid pivot_longer() ja pivot_wider() kaks uut, olulist funktsiooni, mis on mÔeldud andmeraamide transformeerimiseks. pakendist, mille lÔid John Mount ja Nina Zumel.
Tidyr uusima versiooni 0.8.3.9000 installimine
Uue ja kÔige vÀrskema versiooni installimiseks tidyr 0.8.3.9000, milles on saadaval uued funktsioonid, kasutage jÀrgmist koodi.
devtools::install_github("tidyverse/tidyr")
Artikli kirjutamise ajal on need funktsioonid saadaval ainult paketi dev versioonis GitHubis.
Uute funktsioonide kasutusele vÔtmine
Tegelikult pole vanade skriptide uutele funktsioonidele ĂŒleviimine keeruline, et paremini mĂ”ista, kasutan ma vana funktsiooni dokumentatsioonist nĂ€idet ja nĂ€itan, kuidas samu toiminguid saab teha uute pivot_*() funktsioonidega.
Laia vormingu muutmine pikaks.
NĂ€ide koodist gather funktsiooni dokumentatsioonist
# example
library(dplyr)
stocks <- data.frame(
time = as.Date('2009-01-01') + 0:9,
X = rnorm(10, 0, 1),
Y = rnorm(10, 0, 2),
Z = rnorm(10, 0, 4)
)
# old
stocks_gather <- stocks %>% gather(key = stock,
value = price,
-time)
# new
stocks_long <- stocks %>% pivot_longer(cols = -time,
names_to = "stock",
values_to = "price")
Pika vormingu muutmine laieks.
NĂ€ide koodist spread funktsiooni dokumentatsioonist
# old
stocks_spread <- stocks_gather %>% spread(key = stock,
value = price)
# new
stock_wide <- stocks_long %>% pivot_wider(names_from = "stock",
values_from = "price")
Kuna ĂŒlaltoodud nĂ€idetes töödeldes pivot_longer() ja pivot_wider(), ei ole algses tabelis stocks veerusid, mida on loetletud argumentides names_to ja values_to , tuleb nende nimed kirjutada jutumĂ€rkidesse.
Tabel, mille abil on sul kÔige lihtsam aru saada, kuidas liikuda uue kontseptsiooni juurde tidyr.

Autori mÀrkus
Kogu edaspidine tekst on kohandatud, vÔiksin isegi öelda, et vabalt tÔlgitud Tidyverse'i teegi ametlikult veebilehelt.
Lihtne nÀide andmete muutmisest laiast vormist pikaks
pivot_longer () â muudab andmekogusid pikemaks, vĂ€hendades veergude arvu ja suurendades ridade arvu.

Artiklis esitatud nÀidete tÀitmiseks on algselt vaja vajalikud paketid laadida:
library(tidyr)
library(dplyr)
library(readr)Oletame, et meil on kĂŒsitlustulemuste tabel, kus (muuhulgas) kĂŒsiti inimesi nende usu ja aastase sissetuleku kohta:
#> # A tibble: 18 x 11
#> religion `<$10k` `$10-20k` `$20-30k` `$30-40k` `$40-50k` `$50-75k`
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Agnostic 27 34 60 81 76 137
#> 2 Atheist 12 27 37 52 35 70
#> 3 Buddhist 27 21 30 34 33 58
#> 4 Catholic 418 617 732 670 638 1116
#> 5 Donât k⊠15 14 15 11 10 35
#> 6 Evangel⊠575 869 1064 982 881 1486
#> 7 Hindu 1 9 7 9 11 34
#> 8 Histori⊠228 244 236 238 197 223
#> 9 Jehovah⊠20 27 24 24 21 30
#> 10 Jewish 19 19 25 25 30 95
#> # ⊠with 8 more rows, and 4 more variables: `$75-100k` <dbl>,
#> # `$100-150k` <dbl>, `>150k` <dbl>, `Don't know/refused` <dbl>Selles tabelis on esitatud vastajate religiooni andmed ridades ja sissetulekute tase veergude nimedes. Iga kategooria vastajate arv salvestatakse lahtrite vÀÀrtustesse, mis paiknevad religiooni ja sissetuleku taseme ristumiskohas. Tabeli korralikuks ja Ôigeks formaadiks viimiseks piisab, kui kasutada pivot_longer():
pew %>%
pivot_longer(cols = -religion, names_to = "income", values_to = "count")pew %>%
pivot_longer(cols = -religion, names_to = "income", values_to = "count")
#> # A tibble: 180 x 3
#> religion income count
#>
#> 1 Agnostic 2 Agnostic $10-20k 34
#> 3 Agnostic $20-30k 60
#> 4 Agnostic $30-40k 81
#> 5 Agnostic $40-50k 76
#> 6 Agnostic $50-75k 137
#> 7 Agnostic $75-100k 122
#> 8 Agnostic $100-150k 109
#> 9 Agnostic >150k 84
#> 10 Agnostic Don't know/refused 96
#> # ⊠with 170 more rowsFunktsiooni argumendid pivot_longer()
- Esimene argument cols, mÀÀratleb, milliseid veerge on vaja ĂŒhendada. Antud juhul kĂ”ik veerud, vĂ€lja arvatud time.
- Argumendiks names_to annab nime muutuja, mis luuakse ĂŒhendatud veergude nimedest.
- values_to annab nime muutuja, mis luuakse ĂŒhendatud veergude lahtrite vÀÀrtustest.
Spetsifikatsioonid
See on uus funktsioon paketis tidyr, mis oli varem vananenud funktsioonide kasutamisel kÀttesaamatu.
Spetsiifikatsioon on andmeframe, mille iga rida vastab ĂŒhele veergule uues vĂ€ljundandmeframe'is, ja kahele spetsiaalsele veerule, mis algavad:
- .name sisaldab algset veeru nime.
- .value sisaldab veeru nime, kuhu lahtrite vÀÀrtused sisenevad.
ĂlejÀÀnud spetsiifikatsiooni veerud kajastavad seda, kuidas uues veerus kuvatakse kompressitavate veergude nimed. .name.
Spetsiifikatsioon kirjeldab metaandmeid, mis on salvestatud veeru nimes, iga veeru jaoks ĂŒks rida ja iga muutuja jaoks ĂŒks veerg, mis on ĂŒhendatud veeru nimega. Praegu vĂ”ib see mÀÀratlemine tunduda segane, kuid pĂ€rast mitme nĂ€ite uurimist saab kĂ”ik mĂ€rgatavalt selgemaks.
Spetsiifikatsiooni mÔte seisneb selles, et saate kaevata, muuta ja mÀÀrata uusi metaandmeid muundatavale andmeframe'ile.
Tabeli muundamiseks laiast formaadist pikaks kasutab funktsiooni pivot_longer_spec().
Kuidas see funktsioon töötab, see vĂ”tab mis tahes andmeframe'i ja vormib selle metaandmed ĂŒlaltoodud viisil.
NÀiteks vÔtame andmestiku who, mis on saadaval koos paketiga tidyr. See andmestik sisaldab teavet, mida jagab Maailmarebased organizatsioon tuberkuloosiga seonduva haigestumise kohta.
who
#> # A tibble: 7,240 x 60
#> country iso2 iso3 year new_sp_m014 new_sp_m1524 new_sp_m2534
#> & &
#> 1 Afghan⊠AF AFG 1980 NA NA NA
#> 2 Afghan⊠AF AFG 1981 NA NA NA
#> 3 Afghan⊠AF AFG 1982 NA NA NA
#> 4 Afghan⊠AF AFG 1983 NA NA NA
#> 5 Afghan⊠AF AFG 1984 NA NA NA
#> 6 Afghan⊠AF AFG 1985 NA NA NA
#> 7 Afghan⊠AF AFG 1986 NA NA NA
#> 8 Afghan⊠AF AFG 1987 NA NA NA
#> 9 Afghan⊠AF AFG 1988 NA NA NA
#> 10 Afghan⊠AF AFG 1989 NA NA NA
#> # ⊠with 7,230 more rows, and 53 more variablesKoostame selle spetsifikatsiooni.
spec %
pivot_longer_spec(new_sp_m014:newrel_f65, values_to = "count")#> # A tibble: 56 x 3
#> .name .value name
#> <chr> <chr> <chr>
#> 1 new_sp_m014 count new_sp_m014
#> 2 new_sp_m1524 count new_sp_m1524
#> 3 new_sp_m2534 count new_sp_m2534
#> 4 new_sp_m3544 count new_sp_m3544
#> 5 new_sp_m4554 count new_sp_m4554
#> 6 new_sp_m5564 count new_sp_m5564
#> 7 new_sp_m65 count new_sp_m65
#> 8 new_sp_f014 count new_sp_f014
#> 9 new_sp_f1524 count new_sp_f1524
#> 10 new_sp_f2534 count new_sp_f2534
#> # ⊠with 46 more rowsVĂ€ljad country, iso2, iso3 on juba muutujad. Meie ĂŒlesanne on veeretada veerud new_sp_m014 6TB newrel_f65.
Nende veergude nimedes sisaldub jÀrgnev teave:
- Prefiks
new_indikaator, et veerg sisaldab andmeid tuberkuloosi uute juhtude kohta, praegune andmepakk sisaldab teavet ainult uute haigestumiste kohta, seega ei ole antud eesliide praeguses kontekstis mÔttekas. sp/rel/sp/epkirjeldab haiguse diagnoosimise meetodit.m/fpatsiendi sugu.014/1524/2535/3544/4554/65patsiendi vanusevahemik.
Saame neid veerge jagada funktsiooniga extract(), kasutades regulaaravaldisi.
spec %
extract(name, c("diagnosis", "gender", "age"), "new_?(.*)_(.)(.*)")#> # A tibble: 56 x 5
#> .name .value diagnosis gender age
#> <chr> <chr> <chr> <chr> <chr>
#> 1 new_sp_m014 count sp m 014
#> 2 new_sp_m1524 count sp m 1524
#> 3 new_sp_m2534 count sp m 2534
#> 4 new_sp_m3544 count sp m 3544
#> 5 new_sp_m4554 count sp m 4554
#> 6 new_sp_m5564 count sp m 5564
#> 7 new_sp_m65 count sp m 65
#> 8 new_sp_f014 count sp f 014
#> 9 new_sp_f1524 count sp f 1524
#> 10 new_sp_f2534 count sp f 2534
#> # ⊠with 46 more rowsPange tÀhele, et veerg .name peab jÀÀma muutumatuks, kuna see on meie indeks algsete andmestiku veergude nimedes.
Sugu ja vanus (veergude gender ja age) on fikseeritud ja teadaolevad vÀÀrtused, seega on soovitatav muuta need veerud faktoriteks:
spec %
mutate(
gender = factor(gender, levels = c("f", "m")),
age = factor(age, levels = unique(age), ordered = TRUE)
) LÔpuks, et rakendada meie loodud spetsifikatsiooni algsele andmepakile who peame kasutama argumenti spec funktsioonis pivot_longer().
who %>% pivot_longer(spec = spec)
#> # A tibble: 405,440 x 8
#> country iso2 iso3 year diagnosis gender age count
#> <chr> <chr> <chr> <int> <chr> <fct> <ord> <int>
#> 1 Afghanistan AF AFG 1980 sp m 014 NA
#> 2 Afghanistan AF AFG 1980 sp m 1524 NA
#> 3 Afghanistan AF AFG 1980 sp m 2534 NA
#> 4 Afghanistan AF AFG 1980 sp m 3544 NA
#> 5 Afghanistan AF AFG 1980 sp m 4554 NA
#> 6 Afghanistan AF AFG 1980 sp m 5564 NA
#> 7 Afghanistan AF AFG 1980 sp m 65 NA
#> 8 Afghanistan AF AFG 1980 sp f 014 NA
#> 9 Afghanistan AF AFG 1980 sp f 1524 NA
#> 10 Afghanistan AF AFG 1980 sp f 2534 NA
#> # ⊠with 405,430 more rowsKÔike, mida me just tegime, saab visuaalselt kujutada jÀrgmiselt:

MÀÀratlemine mitme vÀÀrtuse (.value) abil
Ălaltoodud nĂ€ites sisaldas spetsifikatsiooni veerg .value ainult ĂŒhte vÀÀrtust, enamasti on see tĂ”si.
Kuid mĂ”nikord vĂ”ib tekkida olukord, kus peate koguma vÀÀrtusi erinevat tĂŒĂŒpi andmete veergudest. Selle saavutamine vananenud funktsiooni abil spread() oleks ĂŒsna keeruline.
Allpool toodud nĂ€ide on ĂŒle vĂ”etud paketist data.table.
LĂ€hme loome harjutusandmestiku.
family <- tibble::tribble(
~family, ~dob_child1, ~dob_child2, ~gender_child1, ~gender_child2,
1L, "1998-11-26", "2000-01-29", 1L, 2L,
2L, "1996-06-22", NA, 2L, NA,
3L, "2002-07-11", "2004-04-05", 2L, 2L,
4L, "2004-10-10", "2009-08-27", 1L, 1L,
5L, "2000-12-05", "2005-02-28", 2L, 1L,
)
family % mutate_at(vars(starts_with("dob")), parse_date)#> # A tibble: 5 x 5
#> family dob_child1 dob_child2 gender_child1 gender_child2
#> <int> <date> <date> <int> <int>
#> 1 1 1998-11-26 2000-01-29 1 2
#> 2 2 1996-06-22 NA 2 NA
#> 3 3 2002-07-11 2004-04-05 2 2
#> 4 4 2004-10-10 2009-08-27 1 1
#> 5 5 2000-12-05 2005-02-28 2 1Loodud andmeraamistiku iga rida sisaldab teavet ĂŒhe pere laste kohta. Peredes vĂ”ib olla ĂŒks vĂ”i kaks last. Iga lapse kohta esitatakse andmed sĂŒnnikuupĂ€eva ja soo kohta, kusjuures iga lapse andmed on eraldi veergudes, meie ĂŒlesanne on viia need andmed analĂŒĂŒsimiseks Ă”ige vormingusse.
Pange tĂ€hele, et meil on kaks muutujat, mis sisaldavad teavet iga lapse kohta: nende sugu ja sĂŒnnikuupĂ€ev (veerud, millel on eessĂ”na dob sisaldavad sĂŒnnikuupĂ€eva, veerud, millel on eessĂ”na gender sisaldavad lapse sugu). Oodatavas tulemus peab need olema eraldi veergudes. Saame teha seda, genereerides spetsifikatsiooni, kus veerg .value nurgel on kaks erinevat vÀÀrtust.
spec %
pivot_longer_spec(-family) %>%
separate(col = name, into = c(".value", "child"))%>%
mutate(child = parse_number(child))
#> # A tibble: 4 x 3
#> .name .value child
#> <chr> <chr> <dbl>
#> 1 dob_child1 dob 1
#> 2 dob_child2 dob 2
#> 3 gender_child1 gender 1
#> 4 gender_child2 gender 2Nii et vaatame samm-sammult, milliseid toiminguid ĂŒlaltoodud kood teostab.
pivot_longer_spec(-family)â loome spetsifikatsiooni, mis kokkusurub kĂ”ik olemasolevad veerud, vĂ€lja arvatud veerg family.separate(col = name, into = c(".value", "child"))â lahutame veeru .name, mis sisaldab algsete vĂ€ljade nimesid, allajoonte jĂ€rgi ja paneme saadud vÀÀrtused veergudesse .value ja laps.mutate(child = parse_number(child))â muundame vĂ€lja vÀÀrtused laps tekstilisest numbriliseks andmetĂŒĂŒbiks.
NĂŒĂŒd saame algsele andmeraamile rakendada saadud spetsifikatsiooni ja viia tabel soovitud vormingusse.
family %>%
pivot_longer(spec = spec, na.rm = T)#> # A tibble: 9 x 4
#> family child dob gender
#> <int> <dbl> <date> <int>
#> 1 1 1 1998-11-26 1
#> 2 1 2 2000-01-29 2
#> 3 2 1 1996-06-22 2
#> 4 3 1 2002-07-11 2
#> 5 3 2 2004-04-05 2
#> 6 4 1 2004-10-10 1
#> 7 4 2 2009-08-27 1
#> 8 5 1 2000-12-05 2
#> 9 5 2 2005-02-28 1Kasutame argumenti na.rm = TRUE, kuna praegune andmevorming sunnib me looma liigseid ridu mitteeksisteerivate vaatluste jaoks. Kuna peres 2 on vaid ĂŒks laps, na.rm = TRUE tagab, et peres 2 on vĂ€ljundandmetes ĂŒks rida.
Andframe'ide muutmine pikast vormist laia vormi
pivot_wider() on on on on on on on on on on on on on on on on on on on on on on on on on on on on on on on on on on on

TĂŒĂŒpi transformatsioon on ÀÀrmiselt harva kasutusel andmete korraldamiseks, kuid see tehnika vĂ”ib olla kasulik kogumite loomisel, mida kasutatakse esitlustes vĂ”i muu tööriistadega integreerimisel.
Tegelikult on funktsioonid pivot_longer() ja pivot_wider() sĂŒmmeetrilised ja teevad ĂŒksteisele vastupidiseid toiminguid, s.t: df %>% pivot_longer(spec = spec) %>% pivot_wider(spec = spec) ja df %>% pivot_wider(spec = spec) %>% pivot_longer(spec = spec) tagasi algse df.
Lihtsaim nÀide tabeli muutmisest laia vormi
Funktsiooni töötamise demonstreerimiseks pivot_wider() kasutame andmekogu fish_encounters, mis sisaldab teavet selle kohta, kuidas erinevad jaamad registreerivad kalade liikumist jÔest.
#> # A tibble: 114 x 3
#> fish station seen
#> <fct> <fct> <int>
#> 1 4842 Release 1
#> 2 4842 I80_1 1
#> 3 4842 Lisbon 1
#> 4 4842 Rstr 1
#> 5 4842 Base_TD 1
#> 6 4842 BCE 1
#> 7 4842 BCW 1
#> 8 4842 BCE2 1
#> 9 4842 BCW2 1
#> 10 4842 MAE 1
#> # ⊠with 104 more rowsEnamasti on see tabel informatiivsem ja kasutajasÔbralikum, kui esitada teavet iga jaama kohta eraldi veerus.
fish_encounters %>% pivot_wider(names_from = station, values_from = seen)
fish_encounters %>% pivot_wider(names_from = station, values_from = seen)
#> # Tibble: 19 x 12
#> fish Release I80_1 Lisbon Rstr Base_TD BCE BCW BCE2 BCW2 MAE
#> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
#> 1 4842 1 1 1 1 1 1 1 1 1 1
#> 2 4843 1 1 1 1 1 1 1 1 1 1
#> 3 4844 1 1 1 1 1 1 1 1 1 1
#> 4 4845 1 1 1 1 1 NA NA NA NA NA
#> 5 4847 1 1 1 NA NA NA NA NA NA NA
#> 6 4848 1 1 1 1 NA NA NA NA NA NA
#> 7 4849 1 1 NA NA NA NA NA NA NA NA
#> 8 4850 1 1 NA 1 1 1 1 NA NA NA
#> 9 4851 1 1 NA NA NA NA NA NA NA NA
#> 10 4854 1 1 NA NA NA NA NA NA NA NA
#> # ⊠veel 9 rida, ja 1 muutuja: MAWSee andmekogum registreerib teavet ainult siis, kui kala on jaama poolt avastatud, st kui mÔni kala ei ole mÔne jaama poolt registreeritud, ei ole neid andmeid tabelis. See tÀhendab, et vÀljundandmed tÀidetakse NA.
Siiski teame, et andme puudumine tÀhendab, et kala ei olnud nÀhtav, seega saame kasutada argumenti values_fill funktsioonis pivot_wider() ja tÀita need puuduolevad vÀÀrtused nullidega:
fish_encounters %>% pivot_wider(
names_from = station,
values_from = seen,
values_fill = list(seen = 0)
)#> # A tibble: 19 x 12
#> fish Release I80_1 Lisbon Rstr Base_TD BCE BCW BCE2 BCW2 MAE
#> <fct> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
#> 1 4842 1 1 1 1 1 1 1 1 1 1
#> 2 4843 1 1 1 1 1 1 1 1 1 1
#> 3 4844 1 1 1 1 1 1 1 1 1 1
#> 4 4845 1 1 1 1 1 0 0 0 0 0
#> 5 4847 1 1 1 0 0 0 0 0 0 0
#> 6 4848 1 1 1 1 0 0 0 0 0 0
#> 7 4849 1 1 0 0 0 0 0 0 0 0
#> 8 4850 1 1 0 1 1 1 1 0 0 0
#> 9 4851 1 1 0 0 0 0 0 0 0 0
#> 10 4854 1 1 0 0 0 0 0 0 0 0
#> # ⊠with 9 more rows, and 1 more variable: MAW <int>Veeru nime genereerimine mitmest algmuutusest
Kujutage ette, et meil on tabel, mis sisaldab toote, riigi ja aasta kombinatsiooni. Testframe'i genereerimiseks saab kasutada jÀrgmist koodi:
df %
filter((product == "A" & country == "AI") | product == "B") %>%
mutate(value = rnorm(nrow(.)))#> # A tibble: 45 x 4
#> product country year value
#> <chr> <chr> <int> <dbl>
#> 1 A AI 2000 -2.05
#> 2 A AI 2001 -0.676
#> 3 A AI 2002 1.60
#> 4 A AI 2003 -0.353
#> 5 A AI 2004 -0.00530
#> 6 A AI 2005 0.442
#> 7 A AI 2006 -0.610
#> 8 A AI 2007 -2.77
#> 9 A AI 2008 0.899
#> 10 A AI 2009 -0.106
#> # ⊠with 35 more rowsMeie ĂŒlesanne on laiendada andmekaarti nii, et ĂŒks veerg sisaldaks andmeid iga toote ja riigi kombinatsiooni kohta. Selleks piisab, kui edastada argument names_from vektor, mis sisaldab ĂŒhendatavate vĂ€ljade nimesid.
df %>% pivot_wider(names_from = c(product, country),
values_from = "value")#> # A tibble: 15 x 4
#> year A_AI B_AI B_EI
#> <int> <dbl> <dbl> <dbl>
#> 1 2000 -2.05 0.607 1.20
#> 2 2001 -0.676 1.65 -0.114
#> 3 2002 1.60 -0.0245 0.501
#> 4 2003 -0.353 1.30 -0.459
#> 5 2004 -0.00530 0.921 -0.0589
#> 6 2005 0.442 -1.55 0.594
#> 7 2006 -0.610 0.380 -1.28
#> 8 2007 -2.77 0.830 0.637
#> 9 2008 0.899 0.0175 -1.30
#> 10 2009 -0.106 -0.195 1.03
#> # ⊠with 5 more rowsSaate samuti rakendada spetsifikatsioone funktsioonile pivot_wider(). Kuid kui see edastatakse pivot_wider() spetsifikatsioon viib lÀbi vastupidise transformatsiooni pivot_longer(): luuakse veerud, mis on mÀÀratud .name, kasutades vÀÀrtusi .value ja teistest veergudest.
Selle andmestiku jaoks saate genereerida kohandatud spetsifikatsiooni, kui soovite, et iga vÔimalik riigi ja toote kombinatsioon oleks oma veerus, mitte ainult need, mis on andmetes olemas:
spec %
expand(product, country, .value = "value") %>%
unite(".name", product, country, remove = FALSE)#> # A tibble: 4 x 4
#> .name product country .value
#> <chr> <chr> <chr> <chr>
#> 1 A_AI A AI value
#> 2 A_EI A EI value
#> 3 B_AI B AI value
#> 4 B_EI B EI valuedf %>% pivot_wider(spec = spec) %>% head()#> # A tibble: 6 x 5
#> year A_AI A_EI B_AI B_EI
#> <int> <dbl> <dbl> <dbl> <dbl>
#> 1 2000 -2.05 NA 0.607 1.20
#> 2 2001 -0.676 NA 1.65 -0.114
#> 3 2002 1.60 NA -0.0245 0.501
#> 4 2003 -0.353 NA 1.30 -0.459
#> 5 2004 -0.00530 NA 0.921 -0.0589
#> 6 2005 0.442 NA -1.55 0.594MÔned edasijÔudnud nÀited uue tidyr kontseptsiooni kasutamisest
Andmete korrastamine USA sissetulekute ja ĂŒĂŒride loenduse andmete nĂ€itel
Andmestik us_rent_income sisaldab teavet USA iga osariigi keskmise sissetuleku ja ĂŒĂŒri kohta 2017. aastal (andmestik on saadaval paketis tidycensus).
us_rent_income
#> # Tibble: 104 x 5
#> GEOID NAME variable estimate moe
#>
#> 1 01 Alabama income 24476 136
#> 2 01 Alabama rent 747 3
#> 3 02 Alaska income 32940 508
#> 4 02 Alaska rent 1200 13
#> 5 04 Arizona income 27517 148
#> 6 04 Arizona rent 972 4
#> 7 05 Arkansas income 23789 165
#> 8 05 Arkansas rent 709 5
#> 9 06 California income 29454 109
#> 10 06 California rent 1358 3
#> # ⊠veel 94 ridaSellises vormis, nagu andmed andmestikus on salvestatud, on nendega töötamine ÀÀrmiselt ebamugav, seetÔttu soovime luua andmestiku veergudega: us_rent_income rent rent_moe, sissetulek, income_moe, . Spetsifikatsiooni loomise jaoks on palju vÔimalusi, kuid peamine on see, et peame genereerima iga muutuja jaestimate/moe , ning seejÀrel genereerima veeru nime.spec % expand(variable, .value = c("estimate", "moe")) %>% mutate( .name = paste0(variable, ifelse(.value == "moe", "_moe", "")) )
Selle spetsifikatsiooni esitamine#> # A tibble: 4 x 3
#> variable .value .name
#> <chr> <chr> <chr>
#> 1 income estimate income
#> 2 income moe income_moe
#> 3 rent estimate rent
#> 4 rent moe rent_moeannab meile tulemuse, mida otsime: pivot_wider() us_rent_income %>% pivot_wider(spec = spec)
us_rent_income %>% pivot_wider(spec = spec)
#> # A tibble: 52 x 6
#> GEOID NAME income income_moe rent rent_moe
#> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
#> 1 01 Alabama 24476 136 747 3
#> 2 02 Alaska 32940 508 1200 13
#> 3 04 Arizona 27517 148 972 4
#> 4 05 Arkansas 23789 165 709 5
#> 5 06 California 29454 109 1358 3
#> 6 08 Colorado 32401 109 1125 5
#> 7 09 Connecticut 35326 195 1123 5
#> 8 10 Delaware 31560 247 1076 10
#> 9 11 District of Columbia 43198 681 1424 17
#> 10 12 Florida 25952 70 1077 3
#> # ⊠with 42 more rowsMaailmapank
MÔnikord nÔuab andmestiku vormimist vajalikku vormi mitu sammu.
Andmestik world_bank_pop kĂ€tkeb maailmapanga andmeid iga riigi rahvaarvu kohta ajavahemikul 2000â2018.
#> # A tibble: 1,056 x 20
#> country indicator `2000` `2001` `2002` `2003` `2004` `2005` `2006`
#> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 ABW SP.URB.T⊠4.24e4 4.30e4 4.37e4 4.42e4 4.47e+4 4.49e+4 4.49e+4
#> 2 ABW SP.URB.G⊠1.18e0 1.41e0 1.43e0 1.31e0 9.51e-1 4.91e-1 -1.78e-2
#> 3 ABW SP.POP.T⊠9.09e4 9.29e4 9.50e4 9.70e4 9.87e+4 1.00e+5 1.01e+5
#> 4 ABW SP.POP.G⊠2.06e0 2.23e0 2.23e0 2.11e0 1.76e+0 1.30e+0 7.98e-1
#> 5 AFG SP.URB.T⊠4.44e6 4.65e6 4.89e6 5.16e6 5.43e+6 5.69e+6 5.93e+6
#> 6 AFG SP.URB.G⊠3.91e0 4.66e0 5.13e0 5.23e0 5.12e+0 4.77e+0 4.12e+0
#> 7 AFG SP.POP.T⊠2.01e7 2.10e7 2.20e7 2.31e7 2.41e+7 2.51e+7 2.59e+7
#> 8 AFG SP.POP.G⊠3.49e0 4.25e0 4.72e0 4.82e0 4.47e+0 3.87e+0 3.23e+0
#> 9 AGO SP.URB.T⊠8.23e6 8.71e6 9.22e6 9.77e6 1.03e+7 1.09e+7 1.15e+7
#> 10 AGO SP.URB.G⊠5.44e0 5.59e0 5.70e0 5.76e0 5.75e+0 5.69e+0 4.92e+0
#> # ⊠with 1,046 more rows, and 11 more variables: `2007` <dbl>,
#> # `2008` <dbl>, `2009` <dbl>, `2010` <dbl>, `2011` <dbl>, `2012` <dbl>,
#> # `2013` <dbl>, `2014` <dbl>, `2015` <dbl>, `2016` <dbl>, `2017` <dbl>Meie eesmÀrk on luua korralik andmestik, kus iga muutuja on eraldi veerus. Praegu pole selge, millised sammud on vajalikud, kuid alustame kÔige ilmsemast probleemist: aasta on jaotatud mitmesse veergu.
Selle parandamiseks tuleb kasutada funktsiooni pivot_longer().
pop2 %
pivot_longer(`2000`:`2017`, names_to = "year")#> # A tibble: 19,008 x 4
#> country indicator year value
#> <chr> <chr> <chr> <dbl>
#> 1 ABW SP.URB.TOTL 2000 42444
#> 2 ABW SP.URB.TOTL 2001 43048
#> 3 ABW SP.URB.TOTL 2002 43670
#> 4 ABW SP.URB.TOTL 2003 44246
#> 5 ABW SP.URB.TOTL 2004 44669
#> 6 ABW SP.URB.TOTL 2005 44889
#> 7 ABW SP.URB.TOTL 2006 44881
#> 8 ABW SP.URB.TOTL 2007 44686
#> 9 ABW SP.URB.TOTL 2008 44375
#> 10 ABW SP.URB.TOTL 2009 44052
#> # ⊠with 18,998 more rowsJÀrgmine samm on arvestada muutuja indicator.
pop2 %>% count(indicator)
#> # A tibble: 4 x 2
#> indicator n
#> <chr> <int>
#> 1 SP.POP.GROW 4752
#> 2 SP.POP.TOTL 4752
#> 3 SP.URB.GROW 4752
#> 4 SP.URB.TOTL 4752Kus SP.POP.GROW on rahvaarvu kasv, SP.POP.TOTL on kogurahvaarv ja SP.URB. * on sama, kuid ainult linnapiirkondade kohta. Jagame need vÀÀrtused kaheks muutujaks: area â piirkond (total vĂ”i urban) ja muutuja, mis sisaldab tegelikke andmeid (population vĂ”i growth):
pop3 %
separate(indicator, c(NA, "area", "variable"))#> # A tibble: 19,008 x 5
#> country area variable year value
#> <chr> <chr> <chr> <chr> <dbl>
#> 1 ABW URB TOTL 2000 42444
#> 2 ABW URB TOTL 2001 43048
#> 3 ABW URB TOTL 2002 43670
#> 4 ABW URB TOTL 2003 44246
#> 5 ABW URB TOTL 2004 44669
#> 6 ABW URB TOTL 2005 44889
#> 7 ABW URB TOTL 2006 44881
#> 8 ABW URB TOTL 2007 44686
#> 9 ABW URB TOTL 2008 44375
#> 10 ABW URB TOTL 2009 44052
#> # ⊠with 18,998 more rowsNĂŒĂŒd peame lihtsalt jagama muutuja variable kaheks veeruks:
pop3 %>%
pivot_wider(names_from = variable, values_from = value)#> # A tibble: 9,504 x 5
#> country area year TOTL GROW
#> <chr> <chr> <chr> <dbl> <dbl>
#> 1 ABW URB 2000 42444 1.18
#> 2 ABW URB 2001 43048 1.41
#> 3 ABW URB 2002 43670 1.43
#> 4 ABW URB 2003 44246 1.31
#> 5 ABW URB 2004 44669 0.951
#> 6 ABW URB 2005 44889 0.491
#> 7 ABW URB 2006 44881 -0.0178
#> 8 ABW URB 2007 44686 -0.435
#> 9 ABW URB 2008 44375 -0.698
#> 10 ABW URB 2009 44052 -0.731
#> # ⊠with 9,494 more rowsKontaktide loend
Viimane nÀide, kujutage ette, et teil on kontaktide nimekiri, mille olete kopeerinud ja kleepinud veebisaidilt:
contacts <- tribble(
~field, ~value,
"name", "Jiena McLellan",
"company", "Toyota",
"name", "John Smith",
"company", "google",
"email", "john@google.com",
"name", "Huxley Ratcliffe"
)Selle nimekirja viimine tabelivormingusse on piisavalt keeruline, kuna puudub muutuja, mis identifitseeriks, millised andmed kuuluvad kummalegi kontaktile. Saame selle parandada, mĂ€rkides, et iga uue kontakti andmed algavad nimest ("name"), seega saame luua unikaalse id-ja iga kord, kui veerus field ilmub vÀÀrtus ânameâ, suurendada seda ĂŒhe vĂ”rra:
contacts %
mutate(
person_id = cumsum(field == "name")
)
contacts#> # A tibble: 6 x 3
#> field value person_id
#> <chr> <chr> <int>
#> 1 name Jiena McLellan 1
#> 2 company Toyota 1
#> 3 name John Smith 2
#> 4 company google 2
#> 5 email john@google.com 2
#> 6 name Huxley Ratcliffe 3NĂŒĂŒd, kui meil on iga kontakti jaoks unikaalne id, saame pöörata field ja value veergudesse:
contacts %>%
pivot_wider(names_from = field, values_from = value)#> # A tibble: 3 x 4
#> person_id name company email
#> <int> <chr> <chr> <chr>
#> 1 1 Jiena McLellan Toyota <NA>
#> 2 2 John Smith google john@google.com
#> 3 3 Huxley Ratcliffe <NA> <NA>KokkuvÔte
Isiklikult arvan, et uus kontseptsioon tidyr on tĂ”eliselt intuitiivsem ja ĂŒletab oluliselt vananenud funktsioone. spread() ja gather()Loodan, et see artikkel aitas teil aru saada pivot_longer() ja pivot_wider().
Allikas: habr.com
