R pakett tidyr ja selle uued funktsioonid pivot_longer ja pivot_wider

Pakett tidyr on ĂŒks populaarsemaid R keele teeke, tidyverse.
Paketi peamine eesmÀrk on andmete korrastamine.

Habr on juba olemas publikatsioon 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.

R pakett tidyr ja selle uued funktsioonid pivot_longer ja pivot_wider

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 telegram ja youtube 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 funktsioonile separate();
  • pivot_longer() — funktsioon, mis muutab andmeid laiast vormist pikaks;
  • pivot_wider() — funktsioon, mis muutab andmeid pikast vormist laiseks. Vastupidine funktsioonile pivot_longer().
  • gather()minenud — funktsioon, mis muutab andmeid laiast vormist pikaks;
  • spread()minenud — funktsioon, mis muutab andmeid pikast vormist laiseks. Vastupidine funktsioonile gather().

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.

R pakett tidyr ja selle uued funktsioonid pivot_longer ja pivot_wider

Autori mÀrkus

Kogu edaspidine tekst on kohandatud, vÔiksin isegi öelda, et vabalt tÔlgitud vignette'idest 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.

R pakett tidyr ja selle uued funktsioonid pivot_longer ja pivot_wider

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 rows

Funktsiooni 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 variables

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

VĂ€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/ep kirjeldab haiguse diagnoosimise meetodit.
  • m/f patsiendi sugu.
  • 014/1524/2535/3544/4554/65 patsiendi 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 rows

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

KÔike, mida me just tegime, saab visuaalselt kujutada jÀrgmiselt:

R pakett tidyr ja selle uued funktsioonid pivot_longer ja pivot_wider

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 vignette'idest 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             1

Loodud 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     2

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

Kasutame 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

R pakett tidyr ja selle uued funktsioonid pivot_longer ja pivot_wider

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 rows

Enamasti 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: MAW

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

Meie ĂŒ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 rows

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

MÔ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 rida

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

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

Maailmapank

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 rows

JĂ€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  4752

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

NĂŒĂŒ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 rows

Kontaktide 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         3

NĂŒĂŒ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

Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster