R paketea tidyr eta bere funtzio berriak pivot_longer eta pivot_wider

pakete txukun R hizkuntzako liburutegi ezagunenetako baten muinean sartuta - txukuna.
Paketearen helburu nagusia datuak forma zehatz batean ekartzea da.

Dagoeneko eskuragarri dago Habré-n argitalpena pakete honi eskainia, baina 2015ekoa da. Eta orain dela egun batzuk bere egileak, Hedley Wickhamek, iragarritako aldaketa berrienak kontatu nahi ditut.

R paketea tidyr eta bere funtzio berriak pivot_longer eta pivot_wider

SJK: Gather() eta spread() zaharkituta geratuko al da?

Hadley Wickham: Neurri batean. Aurrerantzean ez dugu funtzio hauek erabiltzea gomendatuko eta horietan akatsak konponduko, baina paketean egongo dira uneko egoeran.

Edukia

Datuen analisia interesatzen bazaizu, baliteke nirea interesatzea telegrama и youtube kanalak. Eduki gehienak R hizkuntzari eskainitakoak dira.

TidyData kontzeptua

Helburua txukun — datuak forma txukuna deitzen den batera eramaten lagunduko dizu. Datu garbiak datuak dira non:

  • Aldagai bakoitza zutabe batean dago.
  • Behaketa bakoitza kate bat da.
  • Balio bakoitza gelaxka bat da.

Analisiak egiterakoan datu txukunetan aurkezten diren datuekin lan egitea askoz errazagoa eta erosoagoa da.

Tidyr paketean sartzen diren funtzio nagusiak

tidyr-ek taulak eraldatzeko diseinatutako funtzio multzo bat dauka:

  • fill() — falta diren balioak zutabe batean aurreko balioekin betetzea;
  • separate() — eremu bat hainbatetan banatzen du bereizle bat erabiliz;
  • unite() — Hainbat eremu bakarrean konbinatzeko eragiketa egiten du, funtzioaren alderantzizko ekintza separate();
  • pivot_longer() — datuak formatu zabaletik formatu luzera bihurtzen dituen funtzioa;
  • pivot_wider() - datuak formatu luzetik formatu zabalera bihurtzen dituen funtzioa. Funtzioak egiten duenaren alderantzizko eragiketa pivot_longer().
  • gather()zaharkitua — datuak formatu zabaletik formatu luzera bihurtzen dituen funtzioa;
  • spread()zaharkitua - datuak formatu luzetik formatu zabalera bihurtzen dituen funtzioa. Funtzioak egiten duenaren alderantzizko eragiketa gather().

Datuak formatu zabaletik luzera eta alderantziz bihurtzeko kontzeptu berria

Aurretik, funtzioak erabiltzen ziren eraldaketa mota honetarako gather() и spread(). Funtzio hauek egon ziren urteetan zehar, begi bistakoa izan zen erabiltzaile gehienentzat, paketearen egilea barne, funtzio horien izenak eta haien argumentuak ez zirela guztiz agerikoak, eta zailtasunak eragiten zituela horiek aurkitzeko eta funtzio hauetako zein bihurtzen den ulertzeko. data-markoa formatu zabaletik luzera, eta alderantziz.

Ildo horretatik, urtean txukun Bi funtzio berri eta garrantzitsu gehitu dira, data-markoak eraldatzeko diseinatuta daudenak.

Ezaugarri berriak pivot_longer() и pivot_wider() paketearen ezaugarri batzuetan inspiratu ziren cdata, John Mount eta Nina Zumel-ek sortua.

Tidyr 0.8.3.9000 bertsio berriena instalatzen

Paketearen bertsio berria eta berriena instalatzeko txukun 0.8.3.9000, eginbide berriak eskuragarri daudenean, erabili hurrengo kodea.

devtools::install_github("tidyverse/tidyr")

Idazteko unean, funtzio hauek GitHub-en paketearen garapenerako bertsioan bakarrik daude eskuragarri.

Ezaugarri berrietarako trantsizioa

Izan ere, script zaharrak funtzio berriekin lan egiteko bihurtzea ez da zaila, hobeto ulertzeko, funtzio zaharren dokumentaziotik adibide bat hartuko dut eta eragiketa berdinak nola egiten diren erakutsiko dut berriak erabiliz. pivot_*() funtzioak.

Bihurtu formatu zabala formatu luzera.

Bildu funtzioaren dokumentazioko kodea adibidea

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

Formatu luzea formatu zabalera bihurtzea.

Hedapen funtzioaren dokumentazioko kodea adibidea

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

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

Zeren lan egiteko goiko adibideetan pivot_longer() и pivot_wider(), jatorrizko taulan stock argumentuetan zerrendatutako zutaberik ez izenak_to и balioak_to haien izenak komatxo artean egon behar dira.

Kontzeptu berri batekin lanera nola aldatu jakiteko errazen lagunduko dizun taula txukun.

R paketea tidyr eta bere funtzio berriak pivot_longer eta pivot_wider

Egilearen oharra

Beheko testu guztia moldagarria da, itzulpen librea ere esango nuke binetak tidyverse liburutegiko webgune ofizialetik.

Datuak formatu zabaletik luzera bihurtzeko adibide sinplea

pivot_longer () — Datu multzoak luzeagoak egiten ditu, zutabe kopurua murriztuz eta errenkada kopurua handituz.

R paketea tidyr eta bere funtzio berriak pivot_longer eta pivot_wider

Artikuluan aurkezten diren adibideak exekutatzeko, lehenik eta behin beharrezko paketeak konektatu behar dituzu:

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

Demagun taula bat daukagula inkesta baten emaitzekin (besteak beste) jendeari beren erlijioaz eta urteko diru-sarreraz galdetuz:

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

Taula honek inkestatuen erlijio datuak errenkadetan jasotzen ditu, eta diru-sarrera-mailak zutabe-izenetan banatuta daude. Kategoria bakoitzeko inkestatuen kopurua erlijioaren eta errenta-mailaren arteko elkargunean dauden gelaxken balioetan gordetzen da. Taula formatu txukun eta zuzen batean ekartzeko, nahikoa da erabiltzea 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

Funtzio-argudioak pivot_longer()

  • Lehen argumentua lepokoak, zein zutabe batu behar diren deskribatzen du. Kasu honetan, zutabe guztiak izan ezik denbora.
  • Argudioa izenak_to kateatu ditugun zutabeen izenetatik sortuko den aldagaiaren izena ematen du.
  • balioak_to batutako zutabeen gelaxken balioetan gordetako datuetatik sortuko den aldagai baten izena ematen du.

Zehaztapenak

Hau paketearen funtzionaltasun berria da txukun, lehendik erabilgarri ez zegoen funtzio zaharrekin lan egitean.

Zehaztapen bat datu-marko bat da, eta errenkada bakoitza irteera-data-marko berriko zutabe bati dagokio eta honekin hasten diren bi zutabe berezi:

  • . Izena jatorrizko zutabearen izena dauka.
  • .balioa gelaxken balioak edukiko dituen zutabearen izena dauka.

Zehaztapenaren gainerako zutabeek zutabe berriak konprimitutako zutabeen izena nola erakutsiko duten islatzen dute . Izena.

Zehaztapenak zutabe-izen batean gordetako metadatuak deskribatzen ditu, zutabe bakoitzeko errenkada bat eta aldagai bakoitzeko zutabe batekin, zutabe-izenarekin konbinatuta, definizio hau nahasia dirudi une honetan, baina adibide batzuk ikusi ondoren asko bihurtuko da. argiago.

Zehaztapenaren helburua da bihurtzen ari den datu-markoaren metadatu berriak berreskuratu, aldatu eta defini ditzakezula.

Taula formatu zabal batetik formatu luze batera bihurtzean zehaztapenekin lan egiteko, erabili funtzioa pivot_longer_spec().

Funtzio honek nola funtzionatzen duen da edozein data-marko hartzen duela eta bere metadatuak goian azaldutako eran sortzen dituela.

Adibide gisa, har dezagun paketearekin ematen den who datu multzoa txukun. Datu multzo honek nazioarteko osasun erakundeak tuberkulosiaren intzidentziari buruz emandako informazioa jasotzen du.

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

Eraiki ditzagun bere zehaztapena.

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

eremuak herrialde, isoxnumx, isoxnumx aldagaiak dira jada. Gure zeregina zutabeak iraultzea da berria_sp_m014 on newrel_f65.

Zutabe hauen izenek informazio hau gordetzen dute:

  • aurrizki new_ zutabeak tuberkulosi kasu berriei buruzko datuak dituela adierazten du, uneko data-markoak gaixotasun berriei buruzko informazioa baino ez daukala, beraz, egungo testuinguruan aurrizki honek ez du inolako esanahirik.
  • sp/rel/sp/ep gaixotasun bat diagnostikatzeko metodo bat deskribatzen du.
  • m/f pazientearen generoa.
  • 014/1524/2535/3544/4554/65 pazientearen adin tartea.

Funtzioa erabiliz zutabe hauek zati ditzakegu extract()adierazpen erregularra erabiliz.

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

Kontuan izan zutabea . Izena aldatu gabe geratu beharko litzateke, hau gure indizea baita jatorrizko datu-multzoaren zutabe-izenetan.

Generoa eta adina (zutabeak genero и adina) balio finkoak eta ezagunak dituzte, beraz, zutabe hauek faktore bihurtzea gomendatzen da:

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

Azkenik, sortu dugun zehaztapena jatorrizko data markoari aplikatzeko duten argudio bat erabili behar dugu zehaztapenak funtzioan 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

Egin berri dugun guztia eskematikoki honela irudikatu daiteke:

R paketea tidyr eta bere funtzio berriak pivot_longer eta pivot_wider

Hainbat balio erabiliz (.value) zehaztapena

Goiko adibidean, zehaztapenen zutabea .balioa balio bakarra zuen, kasu gehienetan hala da.

Baina noizean behin egoera bat sor daiteke balioetan datu mota desberdinak dituzten zutabeetako datuak bildu behar dituzunean. Oinarrizko funtzio bat erabiliz spread() hori egitea nahiko zaila izango litzateke.

Beheko adibidea hemendik hartua da binetak paketera datuak.taula.

Sortu dezagun prestakuntza datu-markoa.

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

Sortutako data-markoak lerro bakoitzean familia bateko seme-alabei buruzko datuak ditu. Familiek seme-alaba bat edo bi izan ditzakete. Haur bakoitzeko, jaiotegunaren eta generoaren datuak ematen dira, eta ume bakoitzaren datuak zutabe ezberdinetan daude; gure zeregina datu horiek azterketarako formatu egokian jartzea da.

Kontuan izan haur bakoitzari buruzko informazioa duten bi aldagai ditugula: haien sexua eta jaiotze data (aurrizkia duten zutabeak). ondoren jaiotze data, aurrizkia duten zutabeak ditu genero haurraren sexua eduki). Espero den emaitza da zutabe bereizietan agertu behar direla. Hau egin dezakegu zehaztapen bat sortuz zein zutabea .value bi esanahi ezberdin izango ditu.

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

Beraz, ikus ditzagun urratsez urrats goiko kodeak egiten dituen ekintzak.

  • pivot_longer_spec(-family) — Sortu lehendik dauden zutabe guztiak konprimitzen dituen zehaztapena, familiaren zutabea izan ezik.
  • separate(col = name, into = c(".value", "child")) - zatitu zutabea . Izena, sorburu-eremuen izenak biltzen dituena, azpimarra erabiliz eta ondoriozko balioak zutabeetan sartuz .balioa и seme-alaba.
  • mutate(child = parse_number(child)) — eremuen balioak eraldatu seme-alaba testutik zenbakizko datu motara.

Orain lortutako zehaztapena jatorrizko datu-markoan aplikatu eta taula nahi duzun formara eraman dezakegu.

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

Argumentua erabiltzen dugu na.rm = TRUE, datuen uneko formak existitzen ez diren behaketetarako errenkada gehigarriak sortzera behartzen baitu. Zeren 2. familiak ume bakarra du, na.rm = TRUE 2. familiak irteeran errenkada bat izango duela bermatzen du.

Data-markoak formatu luzetik zabalera bihurtzea

pivot_wider() - alderantzizko transformazioa da, eta alderantziz data markoaren zutabe kopurua handitzen du errenkada kopurua murriztuz.

R paketea tidyr eta bere funtzio berriak pivot_longer eta pivot_wider

Eraldaketa mota hau oso gutxitan erabiltzen da datuak forma zehatzetara eramateko, hala ere, teknika hau erabilgarria izan daiteke aurkezpenetan erabiltzen diren taula dinamikoak sortzeko edo beste tresna batzuekin integratzeko.

Izan ere, funtzioak pivot_longer() и pivot_wider() simetrikoak dira, eta elkarren arteko alderantzizko ekintzak sortzen dituzte, hau da: df %>% pivot_longer(spec = spec) %>% pivot_wider(spec = spec) и df %>% pivot_wider(spec = spec) %>% pivot_longer(spec = spec) jatorrizko df itzuliko du.

Taula formatu zabal batera bihurtzeko adibiderik errazena

Funtzioak nola funtzionatzen duen erakusteko pivot_wider() datu multzoa erabiliko dugu arrain_topaketak, geltoki ezberdinek ibaian zehar arrainen mugimendua nola erregistratzen duten buruzko informazioa gordetzen duena.

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

Kasu gehienetan, taula hau informazio gehiago eta erabiltzeko errazago izango da geltoki bakoitzaren informazioa zutabe bereizi batean aurkezten baduzu.

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>

Datu multzo honek estazioak arrainak detektatu dituenean soilik erregistratzen du informazioa, hau da. Estazioren batek arrainren bat erregistratu ez badu, datu hori ez da taulan egongo. Horrek esan nahi du irteera NAz beteko dela.

Hala ere, kasu honetan badakigu erregistrorik ez egoteak arraina ikusi ez dela esan nahi duela, beraz, argumentua erabil dezakegu balioak_bete funtzioan pivot_wider() eta bete falta diren balio hauek zeroz:

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>

Zutabe-izen bat sortzea hainbat iturri-aldagaietatik

Imajinatu produktua, herrialdea eta urtea konbinatzen dituen taula bat dugula. Proba data-markoa sortzeko, honako kodea exekutatu dezakezu:

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

Gure zeregina datu-markoa zabaltzea da, zutabe batek produktuaren eta herrialdearen konbinazio bakoitzeko datuak eduki ditzan. Horretarako, argumentua pasa besterik ez dago izenak_tik batu beharreko eremuen izenak dituen bektore bat.

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

Funtzio bati zehaztapenak ere aplika ditzakezu pivot_wider(). Baina aurkeztutakoan pivot_wider() zehaztapenak kontrako bihurketa egiten du pivot_longer(): atalean zehaztutako zutabeak . Izena, balioak erabiliz .balioa eta beste zutabe batzuk.

Datu multzo honetarako, zehaztapen pertsonalizatu bat sor dezakezu herrialde eta produktu konbinazio posible guztiek bere zutabea izatea nahi baduzu, ez datuetan daudenak bakarrik:

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

Tidyr kontzeptu berriarekin lan egiteko hainbat adibide aurreratu

Datuak garbitzea AEBetako Erroldako Errenta eta Alokairuen datu multzoa adibide gisa erabiliz.

Datu multzoa us_errenta_sarrera 2017rako AEBetako estatu bakoitzaren batez besteko diru-sarreren eta alokairuaren informazioa jasotzen du (paketean eskuragarri dauden datuak errolda txukuna).

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

Datuak datu multzoan gordetzen diren moduan us_errenta_sarrera haiekin lan egitea oso deserosoa da, beraz, zutabeekin datu multzo bat sortu nahiko genuke: alokatzeko, alokatu_moe, nola, errenta_moe. Zehaztapen hau sortzeko modu asko daude, baina puntu nagusia da balio aldakorren konbinazio guztiak sortu behar ditugula eta estimatu/moeeta gero sortu zutabearen izena.

  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

Zehaztapen hau ematea pivot_wider() bilatzen ari garen emaitza ematen digu:

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

Munduko Bankua

Batzuetan, datu-multzo bat nahi den formara eramateak hainbat urrats behar ditu.
Datu multzoa munduko_banku_pop 2000 eta 2018 bitartean herrialde bakoitzeko biztanleriari buruzko Munduko Bankuaren datuak biltzen ditu.

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

Gure helburua aldagai bakoitza bere zutabean datu multzo txukun bat sortzea da. Ez dago argi zein pauso behar diren, baina arazo nabarienetik hasiko gara: urtea hainbat zutabetan banatuta dago.

Hau konpontzeko funtzioa erabili behar duzu 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

Hurrengo urratsa adierazlearen aldagaia aztertzea da.
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

Non SP.POP.GROW biztanleriaren hazkundea den, SP.POP.TOTL biztanleria osoa den eta SP.URB. * gauza bera, baina hiriguneetarako bakarrik. Bana ditzagun balio hauek bi aldagaitan: azalera - azalera (guztira edo hirikoa) eta benetako datuak dituen aldagai bat (biztanleria edo hazkundea):

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

Orain aldagaia bi zutabetan zatitzea besterik ez zaigu geratzen:

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

Kontaktuen zerrenda

Azken adibide bat, imajinatu webgune batetik kopiatu eta itsatsi duzun kontaktu zerrenda bat duzula:

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

Zerrenda hau taularatzea nahiko zaila da, ez baitago aldagairik zein datu zein kontakturi dagozkion identifikatzen duenik. Hau konpondu dezakegu kontaktu berri bakoitzaren datuak "izena"-rekin hasten direla ohartuz, beraz, identifikatzaile esklusibo bat sor dezakegu eta eremuko zutabeak "izena" balioa duen bakoitzean bat handitu dezakegu:

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

Orain kontaktu bakoitzaren ID bakarra dugula, eremua eta balioa zutabeetan bihur ditzakegu:

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>

Ondorioa

Nire iritzi pertsonala kontzeptu berria da txukun benetan intuitiboagoa, eta funtzionalitatean nabarmen handiagoa izan ohi diren funtzioekin alderatuta spread() и gather(). Artikulu honek aurre egiten lagundu izana espero dut pivot_longer() и pivot_wider().

Iturria: www.habr.com

Gehitu iruzkin berria