R pakett tidyr ja selle uued funktsioonid pivot_longer ja pivot_wider.

Pakett tidyr kĂ”igest ĂŒks populaarsemaid R keele teeke — tidyverse.
Pakkumise peamine eesmÀrk on andmete korrektne vormindamine.

Habras on juba olemas publikatsioon selle paketile, kuid see on dateeritud 2015. aastaga. Soovin rÀÀkida kÔige olulisematest muudatustest, millest paar pÀeva 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 aeglaseks?

Hadley Wickham: Teatud mÀÀral. Me lÔpetame nende funktsioonide kasutamise soovitamise ja vigade parandamise, kuid need jÀÀvad paketti senisel kujul.

Sisu

Kui teid huvitab andmeanalĂŒĂŒs, siis vĂ”ivad teile huvi pakkuda minu telegram ja youtube kanalid. Suur osa sisust on pĂŒhendatud R keelele.

TidyData kontseptsioon

EesmĂ€rk tidyr — aidata teil andmed viia nii nimetatud korrastatud vormi. Korrastatud andmed on andmed, kus:

  • Iga muutuja asub veerus.
  • Iga vaatlus on rida.
  • Iga vÀÀrtus on lahtris.

Korrastatud andmetega on analĂŒĂŒsi teostamine oluliselt lihtsam ja mugavam.

Peamised funktsioonid, mis kuuluvad tidyr paketti

tidyr sisaldab funktsioonide kogumit, mis on mÔeldud tabelite muutmiseks:

  • fill() — tĂ€idab puuduvad vÀÀrtused veerus eelnevate vÀÀrtustega;
  • separate() — jagab ĂŒhe vĂ€lja mitmeks, kasutades eraldajat;
  • unite() — teostab mitme vĂ€lja ĂŒhendamise ĂŒheks, vastandav tegevus funktsioonile separate();
  • pivot_longer() — funktsioon, mis muundab andmed laias vormingus pikaks;
  • pivot_wider() — funktsioon, mis muundab andmed pikast vormingust laiaks. Tegevus on vastupidine funktsiooni pivot_longer().
  • gather()aegunud — funktsioon, mis muundab andmed laias vormingus pikaks;
  • spread()aegunud — funktsioon, mis muundab andmed pikast vormingust laiaks. Tegevus on vastupidine funktsiooni gather().

Uus kontseptsioon andmete teisendamisest laiast vormingust pika vorminguni ja vastupidi

Varem kasutati sarnaste transformatsioonide jaoks funktsioone gather() ja spread(). Aastate jooksul on nende funktsioonide kasutamise osas selgunud, et enamikule kasutajatest, sealhulgas paketi autorile, ei ole nende funktsioonide nimed ja argumendid olnud piisavalt selged, tekitades raskusi nende leidmisel ja mÔistmisel, milline neist funktsioonidest muudab andmeframe laia formaadi pikkaks ja vastupidi.

SeetÔttu tidyr on lisatud kaks uut, olulist funktsiooni, mis on mÔeldud andmeframe'i muutmiseks.

Uued funktsioonid pivot_longer() ja pivot_wider() on loodud inspiratsiooni saades mÔnest funktsioonist paketist cdata, mille on vÀlja töötanud John Mount ja Nina Zumel.

Tidyr 0.8.3.9000 kÔige vÀrskema versiooni installimine

Uue, kÔige vÀrskema versiooni paigaldamiseks paketist tidyr 0.8.3.9000, kus on saadaval uued funktsioonid, kasutage jÀrgmisi koodi.

devtools::install_github("tidyverse/tidyr")

Artikli kirjutamise hetkel on need funktsioonid saadaval ainult GitHubi dev versioonis paketist.

Uutele funktsioonidele ĂŒleminek

Tegelikult ei ole vanade skriptide uute funktsioonide kasutusele vÔtmine keeruline, et paremini mÔista, toon nÀite vanade funktsioonide dokumentatsioonist ja nÀitan, kuidas samu toiminguid teostatakse uute pivot_*() funktsioonide abil.

Laiast formaadist pikaks muutmine.

KoodinÀide funktsiooni gather 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")

Pikkforma muutmine laiaks.

KoodinÀide 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 on töötamise osas pivot_longer() ja pivot_wider(), algses tabelis lisamine MSI-sse (uus struktuur) ei too kaasa uute kirjete tekke. ei ole tulpasid, mis on loetletud argumentides names_to ja values_to nende nimed tuleb panna jutumĂ€rkidesse.

Tabel, mille abil on teil kÔige lihtsam aru saada, kuidas alustada uue kontseptsiooniga tidyr.

R pakett tidyr ja selle uued funktsioonid pivot_longer ja pivot_wider.

Autorilt mÀrkus

KĂ”ik edasine tekst on kohandatud, ma ĂŒtleksin, et vaba tĂ”lge vinjetid tidyverse'i ametlikult veebisaidilt.

Lihtne nÀide andmete teisendamisest laiast vormingust pika vorminguni

pivot_longer () — pikendab andmekogumeid, vĂ€hendades veergude arvu ja suurendades ridade arvu.

R pakett tidyr ja selle uued funktsioonid pivot_longer ja pivot_wider.

KÀesolevas artiklis esitatud nÀidete tÀitmiseks tuleb esmalt lisada vajalikud paketid:

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

Oletame, et meil on kĂŒsitlustulemustega tabel, kus (muuhulgas) kĂŒsiti inimesi nende usunde 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>

See tabel sisaldab vastajate religiooniga seotud andmeid ridade kaupa, samas kui sissetuleku tase on jaotatud veergude nimetustes. Iga kategooria vastajate arv on talletatud lahtrite vÀÀrtustes, mis nÀitavad religiooni ja sissetuleku taset. Tabeli toomiseks korralikku, Ôiget vormingusse, 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 Agnostik <$10k                 27
#>  2 Agnostik $10-20k               34
#>  3 Agnostik $20-30k               60
#>  4 Agnostik $30-40k               81
#>  5 Agnostik $40-50k               76
#>  6 Agnostik $50-75k              137
#>  7 Agnostik $75-100k             122
#>  8 Agnostik $100-150k            109
#>  9 Agnostik >150k                 84
#> 10 Agnostik Ei tea/keeldus    96
#> # 
 kokku 170 rida rohkem

Funktsiooni argumendid pivot_longer()

  • Esimene argument cols, kirjeldab, millised veerud tuleb kokku liita. Antud juhul kĂ”ik veerud, vĂ€lja arvatud aeg.
  • Argument names_to annab nime muutujale, mis luuakse veergude nimedest, mida me kokku liitsime.
  • values_to annab nime muutujale, mis luuakse andmetest, mis on talletatud lahtrite vÀÀrtustes kokku liidetud veergudest.

Spetsifikatsioonid

See on uus funktsionaalsus pakendis tidyr, mis oli varem vanade funktsioonide kasutamisel kÀttesaamatu.

Spetsifikatsioon on andmeraam, mille iga rida vastab uue vĂ€ljundi data frame'i ĂŒhele veerule ja kahe eriveerule, mis algavad:

  • .nimi sisaldab algset veeru nime.
  • .value sisaldab veeru nime, kuhu vÀÀrtused sisestatakse.

ÜlejÀÀnud spetsifikatsiooni veerud peegeldavad, kuidas uues veerus kuvatakse tihendatud veergude nimed .nimi.

Spetsifikatsioon kirjeldab veeru nimesse salvestatud metaandmeid, iga veeru jaoks ĂŒks rida ja iga muutuja jaoks ĂŒks veerg, mis on ĂŒhendatud veeru nimega; praegu tundub see mÀÀratlemine vĂ”ib-olla segane, kuid pĂ€rast mitme nĂ€ite vaatamist saab kĂ”ik oluliselt selgemaks.

Spetsifikatsiooni mÔte on see, et saate ekstrapoleerida, muuta ja mÀÀrata uusi metaandmeid muudetavasse data frame'i.

Spetsifikatsioonide töötlemiseks laua muutmisel laiast vormingust pikaks sobib funktsioon pivot_longer_spec().

Kuidas see funktsioon töötab, see vĂ”tab mistahes andmeraami ja koostab selle metaandmed ĂŒlaltoodud viisil.

NÀiteks vÔtame andmestiku who, mis on saadaval koos paketiga. tidyr. See andmestik sisaldab teavet, mida pakub Maailma Terviseorganisatsioon tuberkuloosihaiguse 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
#> # 
 koos 7,230 rohkem rea, ja 53 rohkem muutujat

Loome 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

Muutujad country, iso2, iso3 on juba muutujad. Meie ĂŒlesanne on pöörata veergudega. new_sp_m014 kohta newrel_f65.

Selles veergu nimed sisaldavad jÀrgmist teavet:

  • Eesliide new_ nĂ€itab, et veerg sisaldab andmeid tuberkuloosi uutest juhtumitest; praegune andmeframe sisaldab teavet ainult uute juhtumite kohta, seega ei oma see prefiks antud kontekstis mingit tĂ€henduslikku koormust.
  • sp/rel/sp/ep kirjeldab haiguse diagnoosimise viisi.
  • m/f patsiendi sugu.
  • 014/1524/2535/3544/4554/65 patsiendi vanuserĂŒhm.

Saame neid veerge eraldada funktsiooni abil extract(), kasutades regulaaravatust.

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 .nimi peaks jÀÀma muutumatuks, kuna see on meie indeks veergude nimedes algses andmekogumis.

Sugu ja vanus (veergude gender ja age) omavad fikseeritud ja teadaolevaid vÀÀrtusi, seetÔttu 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 loodud spetsifikatsiooni algsele andmeframe'ile 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

Kogu see, mida me just tegime, vÔib visuaalselt kirjeldada jÀrgmiselt:

R pakett tidyr ja selle uued funktsioonid pivot_longer ja pivot_wider.

Mitu vÀÀrtuse kasutamise spetsiifikatsioon (.value)

Ülaltoodud nĂ€ites sisaldas spetsifikatsiooni veerg .value ainult ĂŒhte vÀÀrtust, mis on enamikul juhtudel tĂ”si.

Kuid harva vĂ”ib tekkida olukord, kus peate koguma vÀÀrtustes andmeid erinevate andmetĂŒĂŒpidega veergudest. Aegunud funktsiooni abil spread() oli seda ĂŒsna keeruline teha.

Allolev nÀide on laenatud vinjetid paketist data.table.

Loome treeningandmestiku.

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 andmestik sisaldab igas reas andmeid ĂŒ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 andmed igasuguse lapse kohta asuvad eraldi veergudes, meie ĂŒlesanne on tuua need andmed analĂŒĂŒsimiseks Ă”iges vormingus.

Pange tĂ€hele, et meil on iga lapse kohta kaks muutujat: tema sugu ja sĂŒnnikuupĂ€ev (veergude, mille eelnevad on dop sisaldavad sĂŒnnikuupĂ€eva, veergude, mille eelnevad on gender sisaldavad lapse soo). Oodatavas tulemuses peavad need olema eraldi veergudes. Saame seda teha, genereerides spetsifikatsiooni, kus veerg .value oma kaht 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 lĂ€bi tegevused, mida ĂŒlaltoodud kood teeb.

  • pivot_longer_spec(-family) — loome spetsifikatsiooni, mis kokku surub kĂ”ik olemasolevad veerud, vĂ€lja arvatud veerg family.
  • separate(col = name, into = c(".value", "child")) — jagame veeru .nimi, mis sisaldab algsete vĂ€ljade nimesid, allajoonimise jĂ€rgi ja paneme saadud vÀÀrtused veergudesse. .value ja laps.
  • mutate(child = parse_number(child)) — muudetakse vĂ€li laps tekstist numbrivÀÀrtuseks.

NĂŒĂŒd saame rakendada saadud spetsifikatsiooni algsele andmereale ja tuua tabeli soovitud vormi.

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 andmevorm sunnib looma ebavajalikke ridu mitteeksisteerivate vaatlustega. Kuna perel 2 on vaid ĂŒks laps, na.rm = TRUE tagab, et perel 2 on vĂ€ljundandmetes vaid ĂŒks rida.

Andframe'ide teisendamine pikast vormingust laia vormingusse

pivot_wider() — on tagasimuundamine, ja vastupidi suurendab andmeraami veergude arvu ridu vĂ€hendades.

R pakett tidyr ja selle uued funktsioonid pivot_longer ja pivot_wider.

Sellist tĂŒĂŒpi muundamist kasutatakse ÀÀrmiselt harva andmete korralikuks vormistamiseks, kuid see tehnika vĂ”ib olla kasulik koostöös aruande tabelite valmistamisel, mis on ette nĂ€htud esitlusteks vĂ”i integratsiooniks teiste tööriistadega.

Tegelikult on funktsioonid pivot_longer() ja pivot_wider() sĂŒmmeetrilised ja teevad teineteisele vastupidiseid toiminguid, st: df %>% pivot_longer(spec = spec) %>% pivot_wider(spec = spec) ja df %>% pivot_wider(spec = spec) %>% pivot_longer(spec = spec) tagastab algse df.

KÔige lihtsam nÀide tabeli viimisest laiasse vormingusse

Funktsiooni töö demonstreerimiseks pivot_wider() kasutame andmekogumit fish_encounters, mis sisaldab teavet selle kohta, kuidas erinevad jaamad fikseerivad kalade liikumist jÔges.

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

Enamikul juhtudel on see tabel informatiivsem ja mugavam kasutada, kui esitada iga jaama teave eraldi veerus.

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
#>        <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 rohkem muutujat: MAW

See andmed salvestavad teavet ainult siis, kui kala on jaama poolt avastatud, st kui mÔni kala pole mingisuguse jaama poolt fikseeritud, ei ole neid andmeid tabelis. See tÀhendab, et vÀljundandmed tÀidetakse NA-ga.

Kuid sel juhul teame, et salvestuse puudumine tÀhendab, et kala ei ole mÀrgatud, seega vÔime kasutada argumenti values_fill funktsioonis pivot_wider() ja tÀita need puuduvad 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 algvariandist

Kujutage ette, et meil on tabel, mis sisaldab toote, riigi ja aasta kombinatsiooni. Testandmestiku mÀÀramiseks saab jÀrgmise koodi kÀivitada:

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 andme raami nii, et ĂŒks veerg sisaldab andmeid iga toote ja riigi kombinatsiooni kohta. Selle saavutamiseks piisab, kui edastada argumenti names_from vektor, mis sisaldab ĂŒhendatavaid 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

Te vÔite ka rakendada spetsifikatsioone sellele funktsioonile. pivot_wider(). Kuid esitamisel pivot_wider() spetsifikatsioon teostab vastupidise teisenduse pivot_longer(): luuakse veerud, mis on mÀÀratud .nimi, kasutades vÀÀrtusi .value ja teistelt veergudelt.

Selle andmestiku jaoks vÔite genereerida kohandatud spetsifikatsiooni, kui soovite, et igal vÔimaliku riigi ja toote kombinatsioonil oleks oma veerg, mitte ainult need, mis on andmetes:

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

Mitmed edasijÔudnud nÀited uue tidyr kontseptsiooni rakendamisest

Andmete korrastamine USA sissetulekute ja ĂŒĂŒriandmete komplekti nĂ€itel

Andmestik us_rent_income sisaldab teavet keskmise sissetuleku ja ĂŒĂŒri kohta igas osariigis Ameerikas 2017. aastal (andmestik on saadaval paketis tidycensus).

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

Sellisel kujul on andmed salvestatud andmestikus us_rent_income nendega töötamine on ÀÀrmiselt ebamugav, seetÔttu sooviksime luua andmestiku, kus on veerud: rent, rent_moe, come, income_moe. On mitmeid viise, kuidas seda spetsifikatsiooni luua, kuid peamine on see, et peame genereerima iga muutujate vÀÀrtuse kombinatsiooni ja estimate/moe, seejÀrel genereerime veeru nime.

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

Selle spetsifikatsiooni esitamine pivot_wider() annab meile tulemuse, mida otsime:

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 andmekogumi viimine soovitud vormi mitmeid samme.
Andmestik world_bank_pop sisaldab Maailmapanga andmeid iga riigi rahvaarvu kohta aastatel 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 asub eraldi veerus. Hetkel pole selge, millised tÀpselt sammud on vajalikud, kuid alustame kÔige ilmsema probleemiga: aasta on jaotatud mitmesse veergu.

Selle parandamiseks on vaja 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 vaadata muutujat 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 – rahvastiku kasv, SP.POP.TOTL – rahvastiku kogus, ning SP.URB. * on sama asi, kuid ainult linnapiirkondade kohta. Jagame need vÀÀrtused kahe muutujaga: 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 vaid 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 vormistamine tabelivormingusse on ĂŒsna keeruline, kuna puudub muutuja, mis tuvastaks, millised andmed kuuluvad konkreetsele kontaktile. Saame seda parandada, mĂ€rkides, et iga uue kontakti andmed algavad nimega ("name"), seega saame luua unikaalse identifikaatori, mille vÀÀrtust suurendame ĂŒksuse vĂ”rra iga kord, kui veerus field esineb vÀÀrtus “name”:

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 ainulaadne identifikaator, saame pöörata vĂ€lja vĂ€lja ja vÀÀrtuse 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 intuitiivselt arusaadavam ja ĂŒletab oluliselt vananenud funktsioone spread() ja gather(). Loodan, et see artikkel aitas teil paremini aru saada pivot_longer() ja pivot_wider().

Allikas: habr.com

Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster