R pakki tidyr og nýju aðgerðir hans pivot_longer og pivot_wider

Pakkinn snyrtilegt innifalinn í kjarna eins vinsælasta bókasafnsins á R tungumálinu - snyrtilegur.
Megintilgangur pakkans er að koma gögnunum á rétt form.

Nú þegar fáanlegt á Habré útgáfu tileinkað þessum pakka, en hann nær aftur til ársins 2015. Og ég vil segja ykkur frá nýjustu breytingunum, sem höfundur hennar, Hedley Wickham, tilkynnti fyrir nokkrum dögum.

R pakki tidyr og nýju aðgerðir hans pivot_longer og pivot_wider

SJK: Verður safna() og dreifa() úrelt?

Hadley Wickham: Að einhverju leyti. Við munum ekki lengur mæla með notkun þessara aðgerða og laga villur í þeim, en þær munu halda áfram að vera til staðar í pakkanum í núverandi ástandi.

efni

Ef þú hefur áhuga á gagnagreiningu gætirðu haft áhuga á mínum símskeyti и YouTube rásir. Mest af efninu er tileinkað R tungumálinu.

TidyData hugtak

Markmið snyrtilegt — hjálpa þér að koma gögnunum á svokallað snyrtilegt form. Snyrtileg gögn eru gögn þar sem:

  • Hver breyta er í dálki.
  • Hver athugun er strengur.
  • Hvert gildi er klefi.

Það er mun auðveldara og þægilegra að vinna með gögn sem eru sett fram í snyrtilegum gögnum þegar unnið er að greiningu.

Helstu aðgerðir innifalinn í tidyr pakkanum

tidyr inniheldur mengi aðgerða sem eru hönnuð til að umbreyta töflum:

  • fill() - fylla upp gildi sem vantar í dálk með fyrri gildum;
  • separate() — skiptir einu sviði í nokkra með því að nota skilju;
  • unite() — framkvæmir þá aðgerð að sameina nokkur svið í eitt, andhverfa aðgerð fallsins separate();
  • pivot_longer() — aðgerð sem breytir gögnum úr breiðsniði í langsnið;
  • pivot_wider() - aðgerð sem breytir gögnum úr löngu sniði í breitt snið. Öfug aðgerð þess sem aðgerðin framkvæmir pivot_longer().
  • gather()gamaldags — aðgerð sem breytir gögnum úr breiðsniði í langsnið;
  • spread()gamaldags - aðgerð sem breytir gögnum úr löngu sniði í breitt snið. Öfug aðgerð þess sem aðgerðin framkvæmir gather().

Ný hugmynd til að umbreyta gögnum úr breitt í langt snið og öfugt

Áður voru föll notuð fyrir þessa tegund umbreytinga gather() и spread(). Í gegnum árin sem þessar aðgerðir voru til varð augljóst að fyrir flesta notendur, þar á meðal höfund pakkans, voru nöfn þessara falla og rök þeirra ekki alveg augljós og ollu erfiðleikum við að finna þær og skilja hvaða af þessum aðgerðum breytir dagsetningarrammi frá breiðu til löngu sniði og öfugt.

Í þessu sambandi, í snyrtilegt Tveimur nýjum mikilvægum aðgerðum hefur verið bætt við sem eru hannaðar til að umbreyta dagsetningarrömmum.

Nýir eiginleikar pivot_longer() и pivot_wider() voru innblásin af sumum eiginleikum pakkans cdata, búin til af John Mount og Ninu Zumel.

Setur upp nýjustu útgáfuna af tidyr 0.8.3.9000

Til að setja upp nýjustu útgáfuna af pakkanum snyrtilegt 0.8.3.9000, þar sem nýir eiginleikar eru fáanlegir, notaðu eftirfarandi kóða.

devtools::install_github("tidyverse/tidyr")

Þegar þetta er skrifað eru þessar aðgerðir aðeins fáanlegar í þróunarútgáfu pakkans á GitHub.

Umskipti yfir í nýja eiginleika

Reyndar er ekki erfitt að flytja gömul forskrift til að vinna með nýjar aðgerðir; til að skilja betur mun ég taka dæmi úr skjölum um gamlar aðgerðir og sýna hvernig sömu aðgerðir eru framkvæmdar með nýjum pivot_*() aðgerðir.

Umbreyttu breitt sniði í langt snið.

Dæmi um kóða úr skjölum fyrir söfnunaraðgerðina

# 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")

Breytir löngu sniði í breitt snið.

Dæmi um kóða úr dreifingaraðgerðaskjölum

# old
stocks_spread <- stocks_gather %>% spread(key = stock, 
                                          value = price) 

# new 
stock_wide    <- stocks_long %>% pivot_wider(names_from  = "stock",
                                            values_from = "price")

Vegna þess að í ofangreindum dæmum um að vinna með pivot_longer() и pivot_wider(), í upprunalegu töflunni birgðir engir dálkar skráðir í rökum nöfn_til и gildi_til nöfn þeirra verða að vera innan gæsalappa.

Tafla sem auðveldar þér að finna út hvernig á að skipta yfir í að vinna með nýtt hugtak snyrtilegt.

R pakki tidyr og nýju aðgerðir hans pivot_longer og pivot_wider

Athugasemd frá höfundi

Allur textinn hér að neðan er aðlögunarhæfur, ég myndi jafnvel segja frjáls þýðing vinjettur frá opinberu vefsíðunni tidyverse bókasafnsins.

Einfalt dæmi um að umbreyta gögnum úr breitt í langt snið

pivot_longer () — gerir gagnasett lengri með því að fækka dálkum og fjölga línum.

R pakki tidyr og nýju aðgerðir hans pivot_longer og pivot_wider

Til að keyra dæmin sem kynnt eru í greininni þarftu fyrst að tengja nauðsynlega pakka:

library(tidyr)
library(dplyr)
library(readr)

Segjum að við höfum töflu með niðurstöðum könnunar sem (meðal annars) spurði fólk um trú þeirra og árstekjur:

#> # 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>

Þessi tafla inniheldur trúarupplýsingar svarenda í röðum og tekjustig eru dreifð yfir dálkanöfn. Fjöldi svarenda úr hverjum flokki er geymdur í frumugildum á mótum trúarbragða og tekjustigs. Til að koma töflunni í snyrtilegt, rétt snið er nóg að nota 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
#>    <chr>    <chr>              <dbl>
#>  1 Agnostic <$10k                 27
#>  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 rows

Aðgerðarrök pivot_longer()

  • Fyrstu rök kraga, lýsir hvaða dálkum þarf að sameina. Í þessu tilviki eru allir dálkar nema tími.
  • Rök nöfn_til gefur nafn breytunnar sem verður til úr nöfnum dálkanna sem við sameinuðum.
  • gildi_til gefur nafn breytu sem verður búin til úr gögnum sem eru geymd í gildum frumna í sameinuðu dálkunum.

Tæknilýsing

Þetta er ný virkni pakkans snyrtilegt, sem áður var ekki tiltækt þegar unnið var með eldri aðgerðir.

Forskrift er gagnarammi, þar sem hver röð samsvarar einum dálki í nýja framleiðsludagarammanum og tveir sérstakir dálkar sem byrja á:

  • . Nafn inniheldur upprunalega dálknafnið.
  • .gildi inniheldur nafn dálksins sem mun innihalda frumugildin.

Dálkarnir sem eftir eru í forskriftinni endurspegla hvernig nýi dálkurinn mun birta heiti þjappaðra dálka frá . Nafn.

Forskriftin lýsir lýsigögnum sem geymd eru í dálknafni, með einni línu fyrir hvern dálk og einum dálki fyrir hverja breytu, ásamt dálknafninu, þessi skilgreining kann að virðast ruglingsleg í augnablikinu, en eftir að hafa skoðað nokkur dæmi verður hún mikið skýrari.

Tilgangurinn með forskriftinni er að þú getur sótt, breytt og skilgreint ný lýsigögn fyrir gagnarammann sem verið er að breyta.

Til að vinna með forskriftir þegar töflu er breytt úr breitt sniði í langt snið, notaðu aðgerðina pivot_longer_spec().

Hvernig þessi aðgerð virkar er að hún tekur hvaða dagsetningarramma sem er og býr til lýsigögn á þann hátt sem lýst er hér að ofan.

Sem dæmi skulum við taka who dataset sem fylgir pakkanum snyrtilegt. Þetta gagnasafn inniheldur upplýsingar frá alþjóðlegu heilbrigðissamtökunum um tíðni berkla.

who
#> # A tibble: 7,240 x 60
#>    country iso2  iso3   year new_sp_m014 new_sp_m1524 new_sp_m2534
#>    <chr>   <chr> <chr> <int>       <int>        <int>        <int>
#>  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 variables

Við skulum byggja forskrift þess.

spec <- who %>%
  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 rows

sviðum land, isoxnumx, isoxnumx eru nú þegar breytur. Verkefni okkar er að fletta dálkunum með new_sp_m014 á newrel_f65.

Nöfn þessara dálka geyma eftirfarandi upplýsingar:

  • Forskeyti new_ gefur til kynna að dálkurinn inniheldur gögn um ný tilfelli berkla, núverandi dagsetningarrammi inniheldur aðeins upplýsingar um nýja sjúkdóma, þannig að þetta forskeytið í núverandi samhengi hefur enga merkingu.
  • sp/rel/sp/ep lýsir aðferð til að greina sjúkdóm.
  • m/f kyn sjúklings.
  • 014/1524/2535/3544/4554/65 aldursbil sjúklings.

Við getum skipt þessum dálkum með aðgerðinni extract()með því að nota reglulega tjáningu.

spec <- 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 rows

Athugið dálkinn . Nafn ætti að vera óbreytt þar sem þetta er vísitalan okkar í dálknöfn upprunalegu gagnasafnsins.

Kyn og aldur (dálkar kyn и Aldur) hafa föst og þekkt gildi, svo það er mælt með því að breyta þessum dálkum í þætti:

spec <-  spec %>%
            mutate(
              gender = factor(gender, levels = c("f", "m")),
              age = factor(age, levels = unique(age), ordered = TRUE)
            ) 

Að lokum, til að beita forskriftinni sem við bjuggum til á upprunalega dagsetningarrammann sem við þurfum að nota rök sérstakur í virkni 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 rows

Allt sem við gerðum er hægt að lýsa með skýringarmynd sem hér segir:

R pakki tidyr og nýju aðgerðir hans pivot_longer og pivot_wider

Forskrift sem notar mörg gildi (.value)

Í dæminu hér að ofan, forskriftardálkurinn .gildi innihélt aðeins eitt gildi, í flestum tilfellum er þetta raunin.

En stundum getur komið upp sú staða þegar þú þarft að safna gögnum úr dálkum með mismunandi gagnategundir í gildum. Notkun eldri aðgerða spread() þetta væri frekar erfitt að gera.

Dæmið hér að neðan er tekið úr vinjettur að pakkanum gögn.tafla.

Við skulum búa til þjálfunargagnaramma.

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 <- 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             1

Stofnaður dagsetningarrammi inniheldur gögn um börn einnar fjölskyldu í hverri röð. Fjölskyldur geta átt eitt eða tvö börn. Fyrir hvert barn eru veitt gögn um fæðingardag og kyn og gögn fyrir hvert barn eru í sérstökum dálkum, verkefni okkar er að koma þessum gögnum á rétt snið til greiningar.

Vinsamlegast athugaðu að við höfum tvær breytur með upplýsingum um hvert barn: kyn þess og fæðingardag (dálkar með forskeytinu DOP innihalda fæðingardag, dálka með forskeyti kyn innihalda kyn barnsins). Áætluð niðurstaða er sú að þær ættu að birtast í aðskildum dálkum. Við getum gert þetta með því að búa til forskrift þar sem dálkurinn .value mun hafa tvær mismunandi merkingar.

spec <- family %>%
  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     2

Svo skulum við skoða skref fyrir skref aðgerðir sem framkvæmdar eru af ofangreindum kóða.

  • pivot_longer_spec(-family) - búðu til forskrift sem þjappar saman öllum núverandi dálkum nema fjölskyldudálknum.
  • separate(col = name, into = c(".value", "child")) - skiptu dálknum . Nafn, sem inniheldur nöfn upprunareitanna, með því að nota undirstrikið og slá inn gildin sem myndast í dálkana .gildi и barn.
  • mutate(child = parse_number(child)) — umbreyta reitgildunum barn frá texta til tölulegra gagnategunda.

Nú getum við beitt forskriftinni sem myndast á upprunalega gagnarammann og fært töfluna í æskilegt form.

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      1

Við notum rök na.rm = TRUE, vegna þess að núverandi form gagnanna þvingar til að búa til auka raðir fyrir athuganir sem ekki eru til. Vegna þess að fjölskylda 2 á aðeins eitt barn, na.rm = TRUE tryggir að fjölskylda 2 mun hafa eina röð í framleiðslunni.

Umbreytir dagsetningarrömmum úr löngu sniði í breitt snið

pivot_wider() - er andhverfa umbreyting, og öfugt eykur fjölda dálka dagsetningarrammans með því að fækka línum.

R pakki tidyr og nýju aðgerðir hans pivot_longer og pivot_wider

Þessi tegund umbreytinga er afar sjaldan notuð til að koma gögnum á nákvæmt form, en þessi tækni getur verið gagnleg til að búa til snúningstöflur sem notaðar eru í kynningum eða til að samþætta við önnur verkfæri.

Reyndar aðgerðir pivot_longer() и pivot_wider() eru samhverf og framkalla aðgerðir andstæða hver við aðra, þ.e. df %>% pivot_longer(spec = spec) %>% pivot_wider(spec = spec) и df %>% pivot_wider(spec = spec) %>% pivot_longer(spec = spec) mun skila upprunalegu df.

Einfaldasta dæmið um að breyta töflu í breitt snið

Til að sýna hvernig aðgerðin virkar pivot_wider() við munum nota gagnasafnið fiska_fundir, sem geymir upplýsingar um hvernig mismunandi stöðvar skrá flutning fiska meðfram ánni.

#> # 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 rows

Í flestum tilfellum verður þessi tafla upplýsandi og auðveldari í notkun ef upplýsingar um hverja stöð eru settar fram í sérstökum dálki.

fish_encounters %>% pivot_wider(names_from = station, values_from = seen)

fish_encounters %>% pivot_wider(names_from = station, values_from = seen)
#> # 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    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
#> # … with 9 more rows, and 1 more variable: MAW <int>

Þetta gagnasafn skráir aðeins upplýsingar þegar fiskur hefur greinst í stöðinni, þ.e. ef einhver fiskur var ekki skráður af einhverri stöð, þá verða þessi gögn ekki í töflunni. Þetta þýðir að úttakið verður fyllt með NA.

Hins vegar í þessu tilfelli vitum við að skortur á skrá þýðir að fiskurinn sást ekki, svo við getum notað rökin values_fill í virkni pivot_wider() og fylltu þessi gildi sem vantar með núllum:

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>

Búa til dálknafn úr mörgum upprunabreytum

Ímyndaðu þér að við höfum töflu sem inniheldur blöndu af vöru, landi og ári. Til að búa til prufudagaramma geturðu keyrt eftirfarandi kóða:

df <- expand_grid(
  product = c("A", "B"), 
  country = c("AI", "EI"), 
  year = 2000:2014
) %>%
  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 rows

Verkefni okkar er að stækka gagnarammann þannig að einn dálkur inniheldur gögn fyrir hverja samsetningu vöru og lands. Til að gera þetta, sendu bara rökin nöfn_frá vektor sem inniheldur nöfn reitanna sem á að sameina.

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 rows

Þú getur líka beitt forskriftum fyrir aðgerð pivot_wider(). En þegar lögð var fram till pivot_wider() forskriftin gerir hið gagnstæða umbreytingu pivot_longer(): Dálkarnir sem tilgreindir eru í . Nafn, með því að nota gildi frá .gildi og öðrum dálkum.

Fyrir þetta gagnasafn geturðu búið til sérsniðna forskrift ef þú vilt að öll möguleg lönd og vörusamsetningar hafi sinn eigin dálk, ekki bara þær sem eru til staðar í gögnunum:

spec <- df %>% 
  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      value

df %>% 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.594

Nokkur háþróuð dæmi um að vinna með nýju tidyr hugmyndinni

Að hreinsa upp gögn með því að nota US Census Income and Rent gagnapakka sem dæmi.

Gagnasett okkur_leigutekjur inniheldur miðgildi tekna og leiguupplýsingar fyrir hvert ríki í Bandaríkjunum fyrir árið 2017 (gagnasett tiltækt í pakka tímatal).

us_rent_income
#> # A tibble: 104 x 5
#>    GEOID NAME       variable estimate   moe
#>    <chr> <chr>      <chr>       <dbl> <dbl>
#>  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
#> # … with 94 more rows

Í því formi sem gögnin eru geymd í gagnasafninu okkur_leigutekjur að vinna með þeim er afar óþægilegt, svo við viljum búa til gagnasett með dálkum: leigja, leigja_moe, Komið, tekju_moe. Það eru margar leiðir til að búa til þessa forskrift, en aðalatriðið er að við þurfum að búa til hverja samsetningu af breytilegum gildum og áætla/moeog búðu til dálknafnið.

  spec <- us_rent_income %>% 
    expand(variable, .value = c("estimate", "moe")) %>% 
    mutate(
      .name = paste0(variable, ifelse(.value == "moe", "_moe", ""))
    )

#> # 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_moe

Veitir þessa forskrift pivot_wider() gefur okkur niðurstöðuna sem við erum að leita að:

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 rows

Alþjóðabankinn

Stundum þarf nokkur skref að koma gagnasetti í æskilegt form.
Gagnasett heimsbankapopp inniheldur gögn Alþjóðabankans um íbúa hvers lands milli 2000 og 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>

Markmið okkar er að búa til snyrtilegt gagnasafn með hverri breytu í sínum dálki. Það er óljóst nákvæmlega hvaða skref eru nauðsynleg, en við byrjum á augljósasta vandamálinu: árið er dreift yfir marga dálka.

Til að laga þetta þarftu að nota aðgerðina pivot_longer().

pop2 <- world_bank_pop %>% 
  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 rows

Næsta skref er að skoða vísisbreytuna.
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  4752

Þar sem SP.POP.GROW er fólksfjölgun, SP.POP.TOTL er heildarfjöldi og SP.URB. * það sama, en aðeins fyrir þéttbýli. Við skulum skipta þessum gildum í tvær breytur: svæði - flatarmál (heildar eða þéttbýli) og breytu sem inniheldur raunveruleg gögn (íbúafjöldi eða vöxtur):

pop3 <- pop2 %>% 
  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 rows

Nú er allt sem við þurfum að gera er að skipta breytunni í tvo dálka:

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 rows

Tengiliðalisti

Eitt síðasta dæmi, ímyndaðu þér að þú sért með tengiliðalista sem þú afritaðir og límdir af vefsíðu:

contacts <- tribble(
  ~field, ~value,
  "name", "Jiena McLellan",
  "company", "Toyota", 
  "name", "John Smith", 
  "company", "google", 
  "email", "[email protected]",
  "name", "Huxley Ratcliffe"
)

Það er frekar erfitt að setja þennan lista í töflu því það er engin breyta sem auðkennir hvaða gögn tilheyra hvaða tengilið. Við getum lagað þetta með því að hafa í huga að gögnin fyrir hvern nýjan tengilið byrja á „nafni“, svo við getum búið til einstakt auðkenni og aukið það um eitt í hvert skipti sem reitsdálkurinn inniheldur gildið „nafn“:

contacts <- 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   [email protected]          2
#> 6 name    Huxley Ratcliffe         3

Nú þegar við höfum einstakt auðkenni fyrir hvern tengilið, getum við breytt reitnum og gildinu í dálka:

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  [email protected]
#> 3         3 Huxley Ratcliffe <NA>    <NA>

Ályktun

Mín persónulega skoðun er sú að nýja hugtakið snyrtilegt sannarlega leiðandi og verulega betri í virkni en eldri aðgerðir spread() и gather(). Ég vona að þessi grein hafi hjálpað þér að takast á við pivot_longer() и pivot_wider().

Heimild: www.habr.com

Bæta við athugasemd