R package tidyr è e so novi funzioni pivot_longer è pivot_wider

Poney urdinatu inclusu in u core di una di e biblioteche più populari in a lingua R - ordinatu.
U scopu principale di u pacchettu hè di portà i dati in una forma precisa.

Dighjà dispunibule nantu à Habré publicazione dedicatu à stu pacchettu, ma data di 2015. È vogliu cuntà di i cambiamenti più attuali, chì sò stati annunziati uni pochi ghjorni fà da u so autore, Hedley Wickham.

R package tidyr è e so novi funzioni pivot_longer è pivot_wider

SJK: Gather () è sparghje () seranu obsoleti ?

Hadley Wickham: In una certa misura. Ùn avemu più ricumandemu l'usu di queste funzioni è correggerà i bug in elli, ma continuanu à esse prisenti in u pacchettu in u so statu attuale.

Cuntenuti

Sè vo site interessatu in l'analisi di dati, pudete esse interessatu in u mo telegram и fratii canali. A maiò parte di u cuntenutu hè dedicatu à a lingua R.

U cuncettu di TidyData

Goal urdinatu - aiutanu à purtà i dati à una forma chjamata neat. I dati puliti sò dati induve:

  • Ogni variabile hè in una colonna.
  • Ogni osservazione hè una stringa.
  • Ogni valore hè una cellula.

Hè assai più faciule è più còmuda di travaglià cù e dati chì sò presentati in dati ordinati quandu facenu analisi.

Funzioni principali incluse in u pacchettu tidyr

tidyr cuntene un inseme di funzioni pensate per trasfurmà e tavule:

  • fill() - riempie i valori mancanti in una colonna cù i valori precedenti;
  • separate() - divide un campu in parechji cù un separatore;
  • unite() - esegue l'operazione di cumminà parechji campi in unu, l'azzione inversa di a funzione separate();
  • pivot_longer() - una funzione chì cunvertisce dati da formatu largu à furmatu longu;
  • pivot_wider() - una funzione chì cunvertisce dati da furmatu longu à furmatu largu. L'operazione inversa di quella realizata da a funzione pivot_longer().
  • gather()obsolet - una funzione chì cunvertisce dati da formatu largu à furmatu longu;
  • spread()obsolet - una funzione chì cunvertisce dati da furmatu longu à furmatu largu. L'operazione inversa di quella realizata da a funzione gather().

Novu cuncettu per a cunversione di dati da u formatu largu à longu è viceversa

Nanzu, e funzioni eranu aduprate per stu tipu di trasfurmazioni gather() и spread(). Nantu à l'anni di esistenza di sti funzioni, hè diventatu evidenti chì per a maiò parte di l'utilizatori, cumpresu l'autore di u pacchettu, i nomi di sti funzioni è i so argumenti ùn eranu micca abbastanza evidenti, è hà causatu difficultà à truvà elli è capisce quale di queste funzioni cunvertisce. un quadru di data da u formatu largu à longu, è viceversa.

In questu sensu, in urdinatu Dui funzioni novi, impurtanti sò state aghjunte chì sò pensate per trasfurmà i frames di data.

Novità pivot_longer() и pivot_wider() sò stati inspirati da alcune di e funziunalità in u pacchettu cdata, creatu da John Mount è Nina Zumel.

Stallà a versione più attuale di tidyr 0.8.3.9000

Per installà a nova versione più attuale di u pacchettu urdinatu 0.8.3.9000, induve e funzioni novi sò dispunibili, utilizate u codice seguente.

devtools::install_github("tidyverse/tidyr")

À u mumentu di a scrittura, queste funzioni sò solu dispunibili in a versione dev di u pacchettu in GitHub.

Transizione à e funzioni novi

In fatti, ùn hè micca difficiule di trasfirià script antichi per travaglià cù e funzioni novi; per capisce megliu, pigliaraghju un esempiu da a documentazione di e funzioni antichi è mostra cumu si facenu e stesse operazioni cù novi. pivot_*() funzioni.

Cunvertisce un furmatu largu à un furmatu longu.

Esempiu di codice da a documentazione di a funzione di raccolta

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

Cunvertisce un furmatu longu à un furmatu largu.

Esempiu di codice da a documentazione di a funzione diffusa

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

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

Perchè in l'esempii sopra di travaglià cù pivot_longer() и pivot_wider(), in a tavula originale Gemiliana nisuna culonna listata in argumenti nomi_à и valori_à i so nomi deve esse in virgolette.

Un tavulinu chì vi aiuterà più facilmente à capisce cumu passà à travaglià cù un novu cuncettu urdinatu.

R package tidyr è e so novi funzioni pivot_longer è pivot_wider

Nota da l'autore

Tuttu u testu quì sottu hè adattatu, diceraghju ancu traduzzione libera vignette da u situ ufficiale di a biblioteca tidyverse.

Un esempiu simplice di cunvertisce dati da u formatu largu à longu

pivot_longer () - rende i setti di dati più longu riducendu u nùmeru di colonne è aumentendu u numeru di fila.

R package tidyr è e so novi funzioni pivot_longer è pivot_wider

Per eseguisce l'esempii presentati in l'articulu, avete prima bisognu di cunnette i pacchetti necessarii:

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

Diciamu chì avemu un tavulu cù i risultati di una indagine chì (frà altre cose) hà dumandatu à e persone nantu à a so religione è u redditu annuale:

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

Questa tavula cuntene i dati di religione di i rispondenti in fila, è i livelli di redditu sò spargugliati in i nomi di colonna. U numeru di rispondenti da ogni categuria hè almacenatu in i valori di e cellule à l'intersezzione di a religione è u livellu di ingressu. Per purtà a tavula in un formatu pulito è currettu, hè abbastanza à aduprà 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

Argumenti di funzione pivot_longer()

  • Primu argumentu colli, descrive quale culonni deve esse unitu. In questu casu, tutte e culonne eccettu tempu.
  • argumentu nomi_à dà u nome di a variàbile chì serà creatu da i nomi di e culonni chì avemu cuncatenatu.
  • valori_à dà u nome di una variàbile chì serà creata da i dati guardati in i valori di e cellule di e culonni fusionati.

Quaternu

Questa hè una nova funziunalità di u pacchettu urdinatu, chì prima ùn era micca dispunibule quandu travagliava cù e funzioni legacy.

Una specificazione hè un quadru di dati, ogni fila di quale currisponde à una colonna in u novu quadru di data di output, è duie colonne speciali chì cumincianu cù:

  • .name cuntene u nome di a colonna originale.
  • .valore cuntene u nome di a colonna chì cuntene i valori di e cellule.

I culonni rimanenti di a specificazione riflettenu cumu a nova colonna mostrarà u nome di e colonne compresse da .name.

A specificazione descrizanu i metadati guardati in un nome di colonna, cù una fila per ogni colonna è una colonna per ogni variàbile, cumminata cù u nome di a colonna, sta definizione pò parè cunfusa à u mumentu, ma dopu avè vistu un pocu di esempi diventerà assai. più chjaru.

U puntu di a specificazione hè chì pudete ritruvà, mudificà è definisce novi metadati per u dataframe chì hè cunvertitu.

Per travaglià cù specificazioni quandu cunvertisce una tavola da un formatu largu à un formatu longu, utilizate a funzione pivot_longer_spec().

Cumu funziona sta funzione hè chì piglia ogni quadru di data è genera i so metadati in a manera descritta sopra.

Cum'è un esempiu, pigliemu u set di dati who chì hè furnitu cù u pacchettu urdinatu. Stu dataset cuntene infurmazione furnita da l'urganizazione internaziunale di salute nantu à l'incidenza di a tuberculosi.

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

Custruemu a so specificazione.

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

campi paese, isoxnumx, isoxnumx sò digià variabili. U nostru compitu hè di flip the columns cun new_sp_m014 nantu newrel_f65.

I nomi di sti culonni guardanu l'infurmazioni seguenti:

  • Prefissu new_ indica chì a colonna cuntene dati nantu à novi casi di tuberculosis, u quadru di data attuale cuntene infurmazioni solu nantu à e malatie novi, cusì stu prefissu in u cuntestu attuale ùn porta micca significatu.
  • sp/rel/sp/ep descrive un metudu per diagnosticà una malatia.
  • m/f sessu di u paziente.
  • 014/1524/2535/3544/4554/65 fascia di età di i pazienti.

Pudemu split sti culonni usendu a funzione extract()usendu l'espressione regulare.

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

Per piacè nutate a colonna .name ùn deve esse micca cambiatu postu chì questu hè u nostru indice in i nomi di colonna di u dataset originale.

Genere è età (colonne genere и etati) anu valori fissi è cunnisciuti, per quessa hè cunsigliatu di cunvertisce sti colonne in fattori:

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

Infine, per applicà a specificazione chì avemu creatu à u quadru di data originale chì avemu bisognu di utilizà un argumentu spec in funzione 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

Tuttu ciò chì avemu appena fattu pò esse schematicamente raffiguratu cusì:

R package tidyr è e so novi funzioni pivot_longer è pivot_wider

Specificazione cù valori multipli (.value)

In l'esempiu sopra, a colonna di specificazione .valore cuntene solu un valore, in a maiò parte di i casi questu hè u casu.

Ma in ocasioni pò esse una situazione quandu avete bisognu di cullà dati da colonne cù diversi tipi di dati in valori. Utilizà una funzione legata spread() questu seria abbastanza difficiule di fà.

L'esempiu sottu hè pigliatu da vignette à u pacchettu dati.tavula.

Creemu un dataframe di furmazione.

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

U quadru di data creatu cuntene dati nantu à i zitelli di una famiglia in ogni linea. E famiglie ponu avè unu o dui figlioli. Per ogni zitellu, i dati sò furniti nantu à a data di nascita è u sessu, è i dati per ogni zitellu sò in colonne separate; u nostru compitu hè di portà queste dati à u formatu currettu per l'analisi.

Per piacè nutate chì avemu duie variàbili cù infurmazioni nantu à ogni zitellu: u so sessu è a data di nascita (columne cù u prefissu). D dop cuntene data di nascita, colonne cù prefissu genere cuntene u sessu di u zitellu). U risultatu aspittatu hè chì deve esse appare in culonni separati. Pudemu fà questu generendu una specificazione in quale a colonna .value averà dui significati diffirenti.

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

Allora, andemu à piglià un ochju passu à passu à l'azzioni realizati da u codice sopra.

  • pivot_longer_spec(-family) - crea una specificazione chì cumpressa tutte e colonne esistenti eccettu a colonna di famiglia.
  • separate(col = name, into = c(".value", "child")) - split the column .name, chì cuntene i nomi di i campi di fonte, usendu u underscore è inserendu i valori resultanti in e colonne .valore и Zitellu.
  • mutate(child = parse_number(child)) - trasfurmà i valori di u campu Zitellu da u testu à u tipu di dati numericu.

Avà pudemu applicà a specificazione resultanti à u dataframe originale è portà a tavula à a forma desiderata.

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

Avemu aduprà argumentu na.rm = TRUE, perchè a forma attuale di e dati forza a creazione di fila extra per osservazioni inesistenti. Perchè a famiglia 2 hà solu un zitellu, na.rm = TRUE guarantisci chì a famiglia 2 hà una fila in u output.

Cunvertisce i frames di data da u formatu longu à u largu

pivot_wider() - hè a trasfurmazioni inversa, è viceversa aumenta u numeru di culonni di u quadru di data riducendu u numeru di fila.

R package tidyr è e so novi funzioni pivot_longer è pivot_wider

Stu tipu di trasfurmazioni hè estremamente raramente utilizatu per portà e dati in una forma precisa, in ogni modu, sta tecnica pò esse utile per creà tabelle pivot usate in presentazioni, o per integrazione cù qualchi altri strumenti.

In fatti, e funzioni pivot_longer() и pivot_wider() sò simmetrici, è produci azzioni inverse l'una à l'altru, vale à dì: df %>% pivot_longer(spec = spec) %>% pivot_wider(spec = spec) и df %>% pivot_wider(spec = spec) %>% pivot_longer(spec = spec) restituverà u df originale.

L'esempiu più simplice di cunvertisce una tavula in un furmatu largu

Per dimustrà cumu funziona a funzione pivot_wider() avemu aduprà u dataset scontri_pesci, chì guarda infurmazione nantu à cumu diverse stazioni registranu u muvimentu di pesci longu u fiume.

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

In a maiò parte di i casi, sta tavula serà più informativa è più faciule d'utilizà se presentate infurmazioni per ogni stazione in una colonna separata.

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>

Stu settore di dati registra solu l'infurmazioni quandu i pesci sò stati rilevati da a stazione, i.e. se un pesciu ùn hè statu registratu da una stazione, allora sta dati ùn saranu micca in a tavula. Questu significa chì l'output serà pienu di NA.

In ogni casu, in questu casu sapemu chì l'absenza di un registru significa chì u pesciu ùn hè micca vistu, cusì pudemu usà l'argumentu. values_fill in funzione pivot_wider() è riempie questi valori mancanti cù zeri:

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>

Generazione di un nome di colonna da parechje variabili fonte

Imagine chì avemu una tavola chì cuntene una cumminazione di produttu, paese è annu. Per generà un quadru di data di prova, pudete eseguisce u codice seguente:

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

U nostru compitu hè di espansione u quadru di dati in modu chì una colonna cuntene dati per ogni cumminazione di pruduttu è paese. Per fà questu, basta à passà l'argumentu nomi_da un vettore chì cuntene i nomi di i campi da unisce.

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

Pudete ancu applicà specificazioni à una funzione pivot_wider(). Ma quandu sottumessi à pivot_wider() a specificazione faci a cunversione opposta pivot_longer(): I culonni specificati in .name, usendu valori da .valore e altre colonne.

Per questu set di dati, pudete generà una specificazione persunalizata se vulete chì ogni paese possibbili è cumminazione di produttu hà a so propria colonna, micca solu quelli prisenti in i dati:

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

Parechji esempii avanzati di travaglià cù u novu cuncettu tidyr

Pulizia di e dati utilizendu u Censu di i Stati Uniti Revenu è Rent dataset cum'è un esempiu.

Set di dati us_rent_income cuntene infurmazione mediana di redditu è ​​affittu per ogni statu in i Stati Uniti per 2017 (set di dati dispunibule in u pacchettu tidycensus).

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

In a forma in quale i dati sò guardati in u dataset us_rent_income travaglià cun elli hè estremamente inconveniente, cusì vulemu creà un settore di dati cù colonne: Appartamenti, affittu_moe, ghjuntu, income_moe. Ci hè parechje manere di creà sta specificazione, ma u puntu principale hè chì avemu bisognu di generà ogni cumminazione di valori variabili è stima / moeè dopu generà u nome di a colonna.

  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

Fornisce sta specificazione pivot_wider() ci dà u risultatu chì circhemu:

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

U Bancu Munniali

Calchì volta portà un settore di dati in a forma desiderata richiede parechji passi.
Dataset world_bank_pop cuntene dati di u Bancu Mundiale nantu à a pupulazione di ogni paese trà 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>

U nostru scopu hè di creà un set di dati pulito cù ogni variabile in a so propria colonna. Ùn hè chjaru esattamente ciò chì i passi sò necessarii, ma avemu da principià cù u prublema più evidenti: l'annu hè spargugliatu in parechje colonne.

Per risolve questu, avete bisognu di utilizà a funzione 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

U prossimu passu hè di guardà a variabile indicatore.
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

Induve SP.POP.GROW hè a crescita di a pupulazione, SP.POP.TOTL hè a pupulazione tutale, è SP.URB. * listessa cosa, ma solu per i zoni urbani. Dividemu sti valori in dui variàbili: area - area (totale o urbana) è una variàbile chì cuntene dati reali (populazione o crescita):

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

Avà tuttu ciò chì avemu da fà hè divisu a variàbile in duie colonne:

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

Lista di cuntatti

Un ultimu esempiu, imagine chì avete una lista di cuntatti chì avete copiatu è incollatu da un situ web:

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

A tabulazione di sta lista hè abbastanza difficiule perchè ùn ci hè micca variabile chì identifica quale dati appartene à quale cuntattu. Pudemu riparà questu nutendu chì i dati di ogni novu cuntattu cumincianu cù "nome", cusì pudemu creà un identificatore unicu è l'incrementu da unu ogni volta chì a colonna di u campu cuntene u valore "nome":

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

Avà chì avemu un ID unicu per ogni cuntattu, pudemu turnà u campu è u valore in colonne:

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>

cunchiusioni

A mo opinione persunale hè chì u novu cuncettu urdinatu veramente più intuitive, è significativamente superiore in funziunalità à e funzioni legacy spread() и gather(). Speru chì questu articulu vi hà aiutatu à trattà pivot_longer() и pivot_wider().

Source: www.habr.com

Add a comment