R pecyn taclus a'i swyddogaethau newydd pivot_longer a pivot_wider

Pecyn taclus cynnwys yng nghraidd un o'r llyfrgelloedd mwyaf poblogaidd yn yr iaith R - taclus.
Prif bwrpas y pecyn yw dod â'r data i ffurf gywir.

Eisoes ar gael ar Habré cyhoeddi ymroddedig i'r pecyn hwn, ond mae'n dyddio'n ôl i 2015. Ac rwyf am ddweud wrthych am y newidiadau mwyaf cyfredol, a gyhoeddwyd ychydig ddyddiau yn ôl gan ei awdur, Hedley Wickham.

R pecyn taclus a'i swyddogaethau newydd pivot_longer a pivot_wider

Mae S.J.K.: A fydd casglu() a lledaenu() yn cael ei anghymeradwyo?

Hadley Wickham: I ryw raddau. Ni fyddwn bellach yn argymell defnyddio'r swyddogaethau hyn ac yn trwsio bygiau ynddynt, ond byddant yn parhau i fod yn bresennol yn y pecyn yn eu cyflwr presennol.

Cynnwys

Os oes gennych ddiddordeb mewn dadansoddi data, efallai y bydd gennych ddiddordeb yn fy telegram и youtube sianeli. Mae'r rhan fwyaf o'r cynnwys wedi'i neilltuo i'r iaith R.

Cysyniad Data Taclus

Nod taclus — eich helpu i ddod â'r data i ffurf daclus, fel y'i gelwir. Data taclus yw data lle:

  • Mae pob newidyn mewn colofn.
  • Mae pob arsylwad yn llinyn.
  • Mae pob gwerth yn gell.

Mae'n llawer haws ac yn fwy cyfleus i weithio gyda data a gyflwynir mewn data taclus wrth gynnal dadansoddiad.

Prif swyddogaethau wedi'u cynnwys yn y pecyn taclus

mae tidyr yn cynnwys set o swyddogaethau a gynlluniwyd i drawsnewid tablau:

  • fill() — llenwi gwerthoedd coll mewn colofn gyda gwerthoedd blaenorol;
  • separate() — yn rhannu un maes yn sawl un gan ddefnyddio gwahanydd;
  • unite() — yn cyflawni gweithrediad cyfuno sawl maes yn un, gweithred gwrthdro'r ffwythiant separate();
  • pivot_longer() — swyddogaeth sy'n trosi data o fformat eang i fformat hir;
  • pivot_wider() - swyddogaeth sy'n trosi data o fformat hir i fformat eang. Gweithrediad cefn yr un a gyflawnir gan y swyddogaeth pivot_longer().
  • gather()hen ffasiwn — swyddogaeth sy'n trosi data o fformat eang i fformat hir;
  • spread()hen ffasiwn - swyddogaeth sy'n trosi data o fformat hir i fformat eang. Gweithrediad cefn yr un a gyflawnir gan y swyddogaeth gather().

Cysyniad newydd ar gyfer trosi data o fformat eang i fformat hir ac i'r gwrthwyneb

Yn flaenorol, defnyddiwyd swyddogaethau ar gyfer y math hwn o drawsnewid gather() и spread(). Dros y blynyddoedd o fodolaeth y swyddogaethau hyn, daeth yn amlwg i'r rhan fwyaf o ddefnyddwyr, gan gynnwys awdur y pecyn, nad oedd enwau'r swyddogaethau hyn a'u dadleuon yn hollol amlwg, a achosodd anawsterau wrth ddod o hyd iddynt a deall pa rai o'r swyddogaethau hyn sy'n trosi. ffrâm dyddiad o fformat llydan i hir, ac i'r gwrthwyneb.

Yn hyn o beth, yn taclus Mae dwy swyddogaeth newydd, bwysig wedi'u hychwanegu sydd wedi'u cynllunio i drawsnewid fframiau dyddiad.

Nodweddion newydd pivot_longer() и pivot_wider() wedi'u hysbrydoli gan rai o'r nodweddion yn y pecyn cdata, a grëwyd gan John Mount a Nina Zumel.

Gosod y fersiwn mwyaf cyfredol o taclus 0.8.3.9000

I osod y fersiwn newydd, mwyaf cyfredol o'r pecyn taclus 0.8.3.9000, lle mae nodweddion newydd ar gael, defnyddiwch y cod canlynol.

devtools::install_github("tidyverse/tidyr")

Ar adeg ysgrifennu, dim ond yn fersiwn datblygu'r pecyn ar GitHub y mae'r swyddogaethau hyn ar gael.

Pontio i nodweddion newydd

Mewn gwirionedd, nid yw'n anodd trosglwyddo hen sgriptiau i weithio gyda swyddogaethau newydd; er mwyn deall yn well, byddaf yn cymryd enghraifft o ddogfennaeth hen swyddogaethau ac yn dangos sut mae'r un gweithrediadau'n cael eu perfformio gan ddefnyddio rhai newydd pivot_*() swyddogaethau.

Trosi fformat eang i fformat hir.

Cod enghreifftiol o ddogfennaeth y swyddogaeth gasglu

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

Trosi fformat hir i fformat eang.

Cod enghreifftiol o ddogfennaeth swyddogaeth taenu

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

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

Achos yn yr enghreifftiau uchod o weithio gyda pivot_longer() и pivot_wider(), yn y tabl gwreiddiol stociau dim colofnau wedi'u rhestru mewn dadleuon enwau_i и gwerthoedd_i rhaid i'w henwau fod mewn dyfynodau.

Tabl a fydd yn eich helpu i ddarganfod yn haws sut i newid i weithio gyda chysyniad newydd taclus.

R pecyn taclus a'i swyddogaethau newydd pivot_longer a pivot_wider

Nodyn gan yr awdur

Mae'r holl destun isod yn addasol, byddwn hyd yn oed yn dweud cyfieithu am ddim vignettes oddi ar wefan swyddogol y llyfrgell taclus.

Enghraifft syml o drosi data o fformat eang i fformat hir

pivot_longer () — yn gwneud setiau data yn hirach trwy leihau nifer y colofnau a chynyddu nifer y rhesi.

R pecyn taclus a'i swyddogaethau newydd pivot_longer a pivot_wider

I redeg yr enghreifftiau a gyflwynir yn yr erthygl, yn gyntaf mae angen i chi gysylltu'r pecynnau angenrheidiol:

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

Gadewch i ni ddweud bod gennym dabl gyda chanlyniadau arolwg a ofynnodd (ymhlith pethau eraill) i bobl am eu crefydd a'u hincwm blynyddol:

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

Mae'r tabl hwn yn cynnwys data crefydd ymatebwyr mewn rhesi, ac mae lefelau incwm wedi'u gwasgaru ar draws enwau colofnau. Mae nifer yr ymatebwyr o bob categori yn cael ei storio yn y gwerthoedd celloedd ar groesffordd crefydd a lefel incwm. Er mwyn dod â'r bwrdd i fformat taclus, cywir, mae'n ddigon i'w ddefnyddio 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

Dadleuon Swyddogaeth pivot_longer()

  • Dadl gyntaf coleri, yn disgrifio pa golofnau sydd angen eu huno. Yn yr achos hwn, pob colofn ac eithrio amser.
  • ddadl enwau_i yn rhoi enw'r newidyn a fydd yn cael ei greu o enwau'r colofnau a gydgatenwyd gennym.
  • gwerthoedd_i yn rhoi enw newidyn a fydd yn cael ei greu o'r data sydd wedi'i storio yng ngwerthoedd celloedd y colofnau cyfun.

Manylebau

Mae hwn yn swyddogaeth newydd o'r pecyn taclus, nad oedd ar gael o'r blaen wrth weithio gyda swyddogaethau etifeddol.

Ffrâm ddata yw manyleb, y mae pob rhes ohoni yn cyfateb i un golofn yn y ffrâm dyddiad allbwn newydd, a dwy golofn arbennig sy'n dechrau gyda:

  • . Enw yn cynnwys enw gwreiddiol y golofn.
  • .gwerth yn cynnwys enw'r golofn a fydd yn cynnwys gwerthoedd y gell.

Mae'r colofnau sy'n weddill yn y fanyleb yn adlewyrchu sut y bydd y golofn newydd yn dangos enw'r colofnau cywasgedig o . Enw.

Mae'r fanyleb yn disgrifio'r metadata sydd wedi'i storio mewn enw colofn, gydag un rhes ar gyfer pob colofn ac un golofn ar gyfer pob newidyn, ynghyd ag enw'r golofn, gall y diffiniad hwn ymddangos yn ddryslyd ar hyn o bryd, ond ar ôl edrych ar ychydig o enghreifftiau bydd yn dod yn llawer cliriach.

Pwynt y fanyleb yw y gallwch adalw, addasu, a diffinio metadata newydd ar gyfer y ffrâm ddata sy'n cael ei throsi.

I weithio gyda manylebau wrth drosi tabl o fformat eang i fformat hir, defnyddiwch y swyddogaeth pivot_longer_spec().

Sut mae'r swyddogaeth hon yn gweithio yw ei fod yn cymryd unrhyw ffrâm dyddiad ac yn cynhyrchu ei fetadata yn y modd a ddisgrifir uchod.

Er enghraifft, gadewch i ni gymryd y set ddata pwy a ddarperir gyda'r pecyn taclus. Mae'r set ddata hon yn cynnwys gwybodaeth a ddarparwyd gan y sefydliad iechyd rhyngwladol ar yr achosion o dwbercwlosis.

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

Gadewch i ni adeiladu ei fanyleb.

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

Maes gwlad, isoxnumx, isoxnumx sydd eisoes yn newidynnau. Ein tasg ni yw troi'r colofnau gyda newydd_sp_m014 ar newrel_f65.

Mae enwau'r colofnau hyn yn storio'r wybodaeth ganlynol:

  • Rhagddodiad new_ yn nodi bod y golofn yn cynnwys data ar achosion newydd o dwbercwlosis, mae'r ffrâm dyddiad cyfredol yn cynnwys gwybodaeth am glefydau newydd yn unig, felly nid oes unrhyw ystyr i'r rhagddodiad hwn yn y cyd-destun presennol.
  • sp/rel/sp/ep yn disgrifio dull o wneud diagnosis o glefyd.
  • m/f rhyw y claf.
  • 014/1524/2535/3544/4554/65 ystod oedran y claf.

Gallwn rannu'r colofnau hyn gan ddefnyddio'r ffwythiant extract()defnyddio mynegiant rheolaidd.

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

Sylwch ar y golofn . Enw aros heb ei newid gan mai hwn yw ein mynegai i enwau colofnau'r set ddata wreiddiol.

Rhyw ac oedran (colofnau rhyw и oedran) â gwerthoedd sefydlog a hysbys, felly argymhellir trosi'r colofnau hyn yn ffactorau:

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

Yn olaf, er mwyn cymhwyso'r fanyleb a grëwyd gennym i'r ffrâm dyddiad gwreiddiol sy'n mae angen inni ddefnyddio dadl spec mewn swyddogaeth 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

Gellir darlunio popeth a wnaethom yn sgematig fel a ganlyn:

R pecyn taclus a'i swyddogaethau newydd pivot_longer a pivot_wider

Manyleb gan ddefnyddio gwerthoedd lluosog (.value)

Yn yr enghraifft uchod, y golofn fanyleb .gwerth cynnwys dim ond un gwerth, yn y rhan fwyaf o achosion mae hyn yn wir.

Ond weithiau gall sefyllfa godi pan fydd angen i chi gasglu data o golofnau gyda gwahanol fathau o ddata mewn gwerthoedd. Defnyddio swyddogaeth etifeddiaeth spread() byddai hyn yn eithaf anodd ei wneud.

Cymerir yr enghraifft isod o vignettes i'r pecyn data.tabl.

Gadewch i ni greu ffrâm data hyfforddi.

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

Mae'r ffrâm dyddiad a grëwyd yn cynnwys data ar blant un teulu ym mhob llinell. Gall fod gan deuluoedd un neu ddau o blant. Ar gyfer pob plentyn, darperir data ar ddyddiad geni a rhyw, ac mae’r data ar gyfer pob plentyn mewn colofnau ar wahân; ein tasg ni yw dod â’r data hwn i’r fformat cywir i’w ddadansoddi.

Sylwch fod gennym ddau newidyn gyda gwybodaeth am bob plentyn: eu rhyw a dyddiad geni (colofnau gyda'r rhagddodiad Dop cynnwys dyddiad geni, colofnau gyda rhagddodiad rhyw cynnwys rhyw y plentyn). Y canlyniad disgwyliedig yw y dylent ymddangos mewn colofnau ar wahân. Gallwn wneud hyn drwy gynhyrchu manyleb y mae'r golofn .value bydd ganddo ddau ystyr gwahanol.

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

Felly, gadewch i ni edrych gam wrth gam ar y camau gweithredu a gyflawnir gan y cod uchod.

  • pivot_longer_spec(-family) — creu manyleb sy'n cywasgu'r holl golofnau presennol ac eithrio'r golofn deulu.
  • separate(col = name, into = c(".value", "child")) - hollti'r golofn . Enw, sy'n cynnwys enwau'r meysydd ffynhonnell, gan ddefnyddio'r tanlinellu a nodi'r gwerthoedd canlyniadol i'r colofnau .gwerth и plentyn.
  • mutate(child = parse_number(child)) — trawsnewid y gwerthoedd maes plentyn o destun i fath data rhifol.

Nawr gallwn gymhwyso'r fanyleb ganlyniadol i'r ffrâm ddata wreiddiol a dod â'r tabl i'r ffurf a ddymunir.

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

Rydym yn defnyddio dadl na.rm = TRUE, oherwydd bod ffurf bresennol y data yn gorfodi creu rhesi ychwanegol ar gyfer arsylwadau nad ydynt yn bodoli. Achos Dim ond un plentyn sydd gan deulu 2, na.rm = TRUE yn gwarantu y bydd gan deulu 2 un rhes yn yr allbwn.

Trosi fframiau dyddiad o fformat hir i eang

pivot_wider() - yw'r trawsnewidiad gwrthdro, ac i'r gwrthwyneb yn cynyddu nifer y colofnau o'r ffrâm dyddiad trwy leihau nifer y rhesi.

R pecyn taclus a'i swyddogaethau newydd pivot_longer a pivot_wider

Anaml iawn y defnyddir y math hwn o drawsnewid i ddod â data i ffurf gywir, fodd bynnag, gall y dechneg hon fod yn ddefnyddiol ar gyfer creu tablau colyn a ddefnyddir mewn cyflwyniadau, neu ar gyfer integreiddio â rhai offer eraill.

Mewn gwirionedd y swyddogaethau pivot_longer() и pivot_wider() yn gymesur, ac yn cynhyrchu gweithredoedd gwrthdro i'w gilydd, h.y.: df %>% pivot_longer(spec = spec) %>% pivot_wider(spec = spec) и df %>% pivot_wider(spec = spec) %>% pivot_longer(spec = spec) yn dychwelyd y df gwreiddiol.

Yr enghraifft symlaf o drosi tabl i fformat eang

I ddangos sut mae'r ffwythiant yn gweithio pivot_wider() byddwn yn defnyddio'r set ddata pysgod_encounters, sy'n storio gwybodaeth am sut mae gwahanol orsafoedd yn cofnodi symudiad pysgod ar hyd yr afon.

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

Yn y rhan fwyaf o achosion, bydd y tabl hwn yn fwy addysgiadol ac yn haws ei ddefnyddio os byddwch yn cyflwyno gwybodaeth ar gyfer pob gorsaf mewn colofn ar wahân.

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>

Mae’r set ddata hon ond yn cofnodi gwybodaeth pan fydd pysgod wedi’u canfod gan yr orsaf, h.y. os na chafodd unrhyw bysgod ei gofnodi gan ryw orsaf, yna ni fydd y data hwn yn y tabl. Mae hyn yn golygu y bydd yr allbwn yn cael ei lenwi â NA.

Fodd bynnag, yn yr achos hwn rydym yn gwybod bod absenoldeb cofnod yn golygu na welwyd y pysgod, felly gallwn ddefnyddio'r ddadl gwerthoedd_lenwi mewn swyddogaeth pivot_wider() a llenwch y gwerthoedd coll hyn gyda sero:

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>

Cynhyrchu enw colofn o newidynnau ffynhonnell lluosog

Dychmygwch fod gennym fwrdd sy'n cynnwys cyfuniad o gynnyrch, gwlad a blwyddyn. I gynhyrchu ffrâm dyddiad prawf, gallwch redeg y cod canlynol:

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

Ein tasg ni yw ehangu'r ffrâm ddata fel bod un golofn yn cynnwys data ar gyfer pob cyfuniad o gynnyrch a gwlad. I wneud hyn, rhowch y ddadl i mewn enwau_o fector yn cynnwys enwau'r meysydd sydd i'w huno.

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

Gallwch hefyd gymhwyso manylebau i swyddogaeth pivot_wider(). Ond pan ymostwng i pivot_wider() mae'r fanyleb yn trosi i'r gwrthwyneb pivot_longer(): Y colofnau a nodir yn . Enw, gan ddefnyddio gwerthoedd o .gwerth a cholofnau eraill.

Ar gyfer y set ddata hon, gallwch gynhyrchu manyleb wedi'i theilwra os ydych chi am i bob gwlad a chyfuniad cynnyrch posibl gael ei golofn ei hun, nid dim ond y rhai sy'n bresennol yn y data:

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

Sawl enghraifft ddatblygedig o weithio gyda'r cysyniad taclus newydd

Glanhau data gan ddefnyddio set ddata Incwm a Rhent Cyfrifiad yr UD fel enghraifft.

Set ddata ni_rhent_incwm yn cynnwys incwm canolrifol a gwybodaeth rhent ar gyfer pob talaith yn UDA ar gyfer 2017 (set ddata ar gael yn y pecyn cyfrif taclus).

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

Ar y ffurf y mae'r data'n cael ei storio yn y set ddata ni_rhent_incwm mae gweithio gyda nhw yn hynod anghyfleus, felly hoffem greu set ddata gyda cholofnau: rhent, rhent_moe, Dewch, incwm_moe. Mae yna lawer o ffyrdd i greu'r fanyleb hon, ond y prif bwynt yw bod angen i ni gynhyrchu pob cyfuniad o werthoedd amrywiol a amcangyfrif/moeac yna cynhyrchu enw'r golofn.

  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

Darparu'r fanyleb hon pivot_wider() yn rhoi'r canlyniad yr ydym yn edrych amdano:

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

Banc y Byd

Weithiau mae angen sawl cam i ddod â set ddata i'r ffurf a ddymunir.
Set ddata byd_banc_pop yn cynnwys data Banc y Byd ar boblogaeth pob gwlad rhwng 2000 a 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>

Ein nod yw creu set ddata daclus gyda phob newidyn yn ei golofn ei hun. Nid yw'n glir yn union pa gamau sydd eu hangen, ond byddwn yn dechrau gyda'r broblem fwyaf amlwg: mae'r flwyddyn wedi'i lledaenu ar draws colofnau lluosog.

Er mwyn trwsio hyn mae angen i chi ddefnyddio'r swyddogaeth 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

Y cam nesaf yw edrych ar y newidyn dangosydd.
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

Lle mae SP.POP.GROW yn dwf poblogaeth, SP.POP.TOTL yw cyfanswm y boblogaeth, a SP.URB. * yr un peth, ond dim ond ar gyfer ardaloedd trefol. Gadewch i ni rannu'r gwerthoedd hyn yn ddau newidyn: ardal - ardal (cyfanswm neu drefol) a newidyn sy'n cynnwys data gwirioneddol (poblogaeth neu dwf):

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

Nawr y cyfan sy'n rhaid i ni ei wneud yw rhannu'r newidyn yn ddwy golofn:

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

Rhestr gyswllt

Un enghraifft olaf, dychmygwch fod gennych restr gyswllt y gwnaethoch ei chopïo a'i phastio o wefan:

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

Mae tablu'r rhestr hon yn eithaf anodd oherwydd nid oes newidyn sy'n nodi pa ddata sy'n perthyn i ba gyswllt. Gallwn drwsio hyn trwy nodi bod data pob cyswllt newydd yn dechrau gyda "enw", fel y gallwn greu dynodwr unigryw a'i gynyddu fesul un bob tro mae colofn y maes yn cynnwys y gwerth "enw":

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

Nawr bod gennym ID unigryw ar gyfer pob cyswllt, gallwn droi'r maes a'r gwerth yn golofnau:

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>

Casgliad

Fy marn bersonol yw bod y cysyniad newydd taclus yn wirioneddol fwy sythweledol, ac yn sylweddol well o ran ymarferoldeb i swyddogaethau etifeddol spread() и gather(). Rwy'n gobeithio bod yr erthygl hon wedi eich helpu i ddelio â hi pivot_longer() и pivot_wider().

Ffynhonnell: hab.com

Ychwanegu sylw