R багц tidyr болон түүний шинэ функцууд илүү урт ба pivot_wider

Багц эмх цэгцтэй R хэл дээрх хамгийн алдартай номын сангийн цөмд багтсан - эмх цэгцтэй.
Багцын гол зорилго нь өгөгдлийг үнэн зөв хэлбэрт оруулах явдал юм.

Habré дээр аль хэдийн боломжтой нийтлэл энэ багцад зориулагдсан боловч энэ нь 2015 оноос эхтэй. Хэдэн өдрийн өмнө зохиогч Хедли Уикхамын зарласан хамгийн сүүлийн үеийн өөрчлөлтүүдийн талаар би танд хэлэхийг хүсч байна.

R багц tidyr болон түүний шинэ функцууд илүү урт ба pivot_wider

С.Ж.К.: gather() болон spread() хүчингүй болох уу?

Хэдли Викхэм: Ямар нэг хэмжээгээр. Бид цаашид эдгээр функцийг ашиглахыг зөвлөдөггүй бөгөөд тэдгээрт гарсан алдааг засахгүй, гэхдээ тэдгээр нь одоогийн байдлаар багцад байсаар байх болно.

Агуулга

Хэрэв та өгөгдлийн шинжилгээг сонирхож байгаа бол миний мэдээллийг сонирхож магадгүй юм цахилгаан мэдээ и YouTube-ийн сувгууд. Ихэнх контент нь R хэлэнд зориулагдсан.

TidyData ойлголт

Зорилго эмх цэгцтэй - таны өгөгдлийг цэвэр хэлбэрт оруулахад тусална уу. Цэвэр өгөгдөл нь дараах өгөгдөл юм:

  • Хувьсагч бүр баганад байна.
  • Ажиглалт бүр нь мөр юм.
  • Утга бүр нь нүд юм.

Шинжилгээ хийхдээ эмх цэгцтэй өгөгдөлд оруулсан өгөгдөлтэй ажиллах нь илүү хялбар бөгөөд илүү хялбар байдаг.

Tidyr багцад багтсан үндсэн функцууд

tidyr нь хүснэгтийг хувиргахад зориулагдсан багц функцуудыг агуулдаг.

  • fill() - баганад дутуу утгыг өмнөх утгуудаар бөглөх;
  • separate() — нэг талбарыг ялгагч ашиглан хэд хэдэн болгон хуваана;
  • unite() - функцийн урвуу үйлдэл болох хэд хэдэн талбарыг нэг болгон нэгтгэх үйлдлийг гүйцэтгэдэг separate();
  • pivot_longer() — өгөгдлийг өргөн форматаас урт формат руу хөрвүүлдэг функц;
  • pivot_wider() - өгөгдлийг урт форматаас өргөн формат руу хөрвүүлдэг функц. Функцээр гүйцэтгэсэн үйлдлийн урвуу үйлдэл pivot_longer().
  • gather()хуучирсан — өгөгдлийг өргөн форматаас урт формат руу хөрвүүлдэг функц;
  • spread()хуучирсан - өгөгдлийг урт форматаас өргөн формат руу хөрвүүлдэг функц. Функцээр гүйцэтгэсэн үйлдлийн урвуу үйлдэл gather().

Өгөгдлийг өргөн форматаас урт формат руу хөрвүүлэх шинэ ойлголт

Өмнө нь энэ төрлийн хувиргалтанд функцуудыг ашигладаг байсан gather() и spread(). Эдгээр функцууд оршин тогтнож байсан олон жилийн туршид ихэнх хэрэглэгчдийн хувьд, түүний дотор багц зохиогчийн хувьд эдгээр функцүүдийн нэрс, тэдгээрийн аргументууд нь тийм ч тодорхой биш байсан нь тодорхой болсон бөгөөд тэдгээрийг олох, эдгээр функцүүдийн аль нь хөрвүүлдэг болохыг ойлгоход бэрхшээлтэй байсан. өргөнөөс урт формат руу огнооны хүрээ, мөн эсрэгээр.

Үүнтэй холбогдуулан in эмх цэгцтэй Огнооны хүрээг хувиргах зориулалттай хоёр шинэ чухал функц нэмэгдсэн.

Шинэ боломжууд pivot_longer() и pivot_wider() багцын зарим онцлогоос санаа авсан cдата, Жон Маунт, Нина Зумел нарын бүтээсэн.

tidyr 0.8.3.9000-ийн хамгийн сүүлийн хувилбарыг суулгаж байна

Багцын шинэ, хамгийн сүүлийн хувилбарыг суулгахын тулд эмх цэгцтэй 0.8.3.9000, шинэ боломжууд байгаа бол дараах кодыг ашиглана уу.

devtools::install_github("tidyverse/tidyr")

Бичиж байх үед эдгээр функцууд нь зөвхөн GitHub дээрх багцын хөгжүүлэлтийн хувилбарт байдаг.

Шинэ функцүүдэд шилжих

Үнэн хэрэгтээ хуучин скриптүүдийг шинэ функцтэй ажиллахад шилжүүлэх нь тийм ч хэцүү биш бөгөөд илүү сайн ойлгохын тулд би хуучин функцүүдийн баримт бичгээс жишээ авч, шинэ функцуудыг ашиглан ижил үйлдлүүд хэрхэн хийгддэгийг харуулах болно. pivot_*() функцууд.

Өргөн форматыг урт формат руу хөрвүүлэх.

Цуглуулах функцийн баримт бичгийн жишээ код

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

Урт форматыг өргөн формат руу хөрвүүлэх.

Тархалтын функцийн баримт бичгийн жишээ код

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

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

Учир нь хамтран ажиллах дээрх жишээнүүдэд pivot_longer() и pivot_wider(), эх хүснэгтэд хувьцаанууд аргументуудад жагсаасан багана байхгүй нэрс и утгууд тэдний нэр хашилтанд байх ёстой.

Шинэ үзэл баримтлалтай ажиллахад хэрхэн шилжихийг хялбархан олоход туслах хүснэгт эмх цэгцтэй.

R багц tidyr болон түүний шинэ функцууд илүү урт ба pivot_wider

Зохиогчийн тэмдэглэл

Доорх бүх текст нь дасан зохицох чадвартай, би үнэгүй орчуулга ч гэж хэлмээр байна виньеттууд tidyverse номын сангийн албан ёсны вэбсайтаас.

Өгөгдлийг өргөн форматаас урт формат руу хөрвүүлэх энгийн жишээ

pivot_longer () — баганын тоог багасгаж, мөрийн тоог нэмэгдүүлснээр өгөгдлийн багцыг уртасгана.

R багц tidyr болон түүний шинэ функцууд илүү урт ба pivot_wider

Нийтлэлд үзүүлсэн жишээнүүдийг ажиллуулахын тулд эхлээд шаардлагатай багцуудыг холбох хэрэгтэй.

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

Хүмүүсийн шашин шүтлэг, жилийн орлогын талаар (бусад зүйлсээс гадна) асуусан судалгааны үр дүн бүхий хүснэгттэй гэж үзье.

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

Энэ хүснэгтэд санал асуулгад оролцогчдын шашин шүтлэгийн талаарх мэдээллийг мөрөнд багтаасан бөгөөд орлогын түвшинг баганын нэрээр тараасан байна. Ангилал тус бүрийн санал асуулгад оролцогчдын тоог шашин ба орлогын түвшний огтлолцол дахь эсийн утгуудад хадгалдаг. Хүснэгтийг цэвэр, зөв ​​форматтай болгохын тулд үүнийг ашиглахад хангалттай 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

Функцийн аргументууд pivot_longer()

  • Эхний аргумент хүзүүвч, аль баганыг нэгтгэх шаардлагатайг тайлбарлана. Энэ тохиолдолд бусад бүх багана цаг хугацаа.
  • баталгаа нэрс нь бидний холбосон баганын нэрнээс үүсэх хувьсагчийн нэрийг өгнө.
  • утгууд нэгтгэсэн баганын нүднүүдийн утгуудад хадгалагдсан өгөгдлөөс үүсэх хувьсагчийн нэрийг өгнө.

Спецификации

Энэ бол багцын шинэ функц юм эмх цэгцтэй, энэ нь өмнө нь хуучин функцуудтай ажиллахад боломжгүй байсан.

Тодорхойлолт нь өгөгдлийн хүрээ бөгөөд мөр бүр нь шинэ гаралтын огнооны хүрээн дэх нэг багана болон дараахаас эхэлдэг хоёр тусгай баганатай тохирч байна.

  • .Нэр баганын анхны нэрийг агуулна.
  • .утга нүдний утгуудыг агуулсан баганын нэрийг агуулна.

Тодорхойлолтын үлдсэн баганууд нь шинэ баганад шахсан баганын нэрийг хэрхэн харуулахыг тусгасан болно .Нэр.

Тодорхойлолт нь баганын нэрэнд хадгалагдсан мета өгөгдлүүдийг тайлбарласан бөгөөд багана тус бүрд нэг мөр, хувьсагч тус бүрт нэг багана, баганын нэртэй хослуулсан нь энэ тодорхойлолт нь одоогоор ойлгомжгүй мэт санагдаж болох ч цөөн хэдэн жишээг харсны дараа энэ нь их байх болно. илүү тодорхой.

Тодорхойлолтын гол зүйл бол хөрвүүлж буй дата фреймийн шинэ мета өгөгдлийг олж авах, өөрчлөх, тодорхойлох боломжтой юм.

Хүснэгтийг өргөн форматаас урт формат руу хөрвүүлэхдээ техникийн үзүүлэлтүүдтэй ажиллахын тулд функцийг ашиглана уу pivot_longer_spec().

Энэ функц нь ямар ч огнооны хүрээг авч, дээр дурдсан аргаар мета өгөгдлийг үүсгэдэг.

Жишээ болгон багцад өгсөн who датасетийг авч үзье эмх цэгцтэй. Энэхүү мэдээллийн багц нь сүрьеэгийн өвчлөлийн талаарх олон улсын эрүүл мэндийн байгууллагаас өгсөн мэдээллийг агуулдаг.

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

Түүний техникийн үзүүлэлтийг бүтээцгээе.

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

талбарууд улс, isoxnumx, isoxnumx аль хэдийн хувьсагч байна. Бидний даалгавар бол баганыг эргүүлэх явдал юм new_sp_m014 дээр newrel_f65.

Эдгээр баганын нэр нь дараах мэдээллийг хадгалдаг.

  • Угтвар new_ Энэ баганад сүрьеэгийн шинэ тохиолдлын талаарх мэдээллийг агуулж байгааг харуулж байгаа бол одоогийн огнооны хүрээ нь зөвхөн шинэ өвчний мэдээллийг агуулж байгаа тул одоогийн нөхцөлд энэ угтвар ямар ч утга агуулаагүй болно.
  • sp/rel/sp/ep өвчнийг оношлох аргыг тайлбарладаг.
  • m/f өвчтөний хүйс.
  • 014/1524/2535/3544/4554/65 өвчтөний насны хүрээ.

Бид функцийг ашиглан эдгээр баганыг хувааж болно extract()тогтмол илэрхийлэл ашиглах.

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

Баганыг анхаарна уу .Нэр Энэ нь бидний анхны өгөгдлийн багцын баганын нэрсийн индекс учраас өөрчлөгдөхгүй байх ёстой.

Хүйс ба нас (багана хүйс и нас) нь тогтмол бөгөөд мэдэгдэж байгаа утгуудтай тул эдгээр баганыг хүчин зүйл болгон хөрвүүлэхийг зөвлөж байна:

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

Эцэст нь, бидний үүсгэсэн тодорхойлолтыг анхны огнооны хүрээнд хэрэгжүүлэхийн тулд хэн Бид аргумент ашиглах хэрэгтэй SPEC функцэд 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

Бидний хийсэн бүх зүйлийг схемийн дагуу дараах байдлаар дүрсэлж болно.

R багц tidyr болон түүний шинэ функцууд илүү урт ба pivot_wider

Олон утгыг ашигласан тодорхойлолт (.утга)

Дээрх жишээнд тодорхойлолтын багана .утга зөвхөн нэг утгыг агуулж байсан бөгөөд ихэнх тохиолдолд ийм байдаг.

Гэхдээ заримдаа өөр өөр төрлийн өгөгдлийн утгууд бүхий баганаас мэдээлэл цуглуулах шаардлагатай нөхцөл байдал үүсч болно. Хуучин функцийг ашиглаж байна spread() үүнийг хийхэд нэлээд хэцүү байх болно.

Доорх жишээг эндээс авсан болно виньеттууд багц руу мэдээлэл.хүснэгт.

Сургалтын дата фрейм үүсгэцгээе.

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

Үүсгэсэн огнооны хүрээ нь мөр бүрт нэг гэр бүлийн хүүхдүүдийн мэдээллийг агуулдаг. Гэр бүлүүд нэг эсвэл хоёр хүүхэдтэй байж болно. Хүүхэд бүрийн хувьд төрсөн огноо, хүйсийн талаархи мэдээллийг өгдөг бөгөөд хүүхэд бүрийн мэдээллийг тусдаа баганад байрлуулсан бөгөөд бидний даалгавар бол энэ өгөгдлийг дүн шинжилгээ хийх зөв формат руу оруулах явдал юм.

Бидэнд хүүхэд бүрийн талаарх мэдээлэл бүхий хоёр хувьсагч байгааг анхаарна уу: тэдний хүйс, төрсөн он сар өдөр (угтвар бүхий багана). доп төрсөн он сар өдөр, угтвар бүхий багануудыг агуулна хүйс хүүхдийн хүйсийг агуулсан). Хүлээгдэж буй үр дүн нь тэдгээрийг тусдаа баганад харуулах явдал юм. Бид багана байгаа тодорхойлолтыг бий болгосноор үүнийг хийж чадна .value гэсэн хоёр өөр утгатай болно.

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

Ингээд дээрх кодоор хийгдсэн үйлдлүүдийг алхам алхмаар авч үзье.

  • pivot_longer_spec(-family) — гэр бүлийн баганаас бусад одоо байгаа бүх баганыг шахах тодорхойлолтыг үүсгэ.
  • separate(col = name, into = c(".value", "child")) - баганыг хуваах .Нэр, доод зураасыг ашиглан эх талбаруудын нэрийг агуулсан ба үр дүнгийн утгыг баганад оруулна. .утга и Хүүхэд.
  • mutate(child = parse_number(child)) - талбайн утгыг хувиргах Хүүхэд текстээс тоон өгөгдлийн төрөл хүртэл.

Одоо бид үр дүнгийн тодорхойлолтыг анхны dataframe-д хэрэглэж, хүснэгтийг хүссэн хэлбэрт оруулж болно.

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

Бид аргумент ашигладаг na.rm = TRUE, учир нь өгөгдлийн одоогийн хэлбэр нь байхгүй ажиглалтын нэмэлт мөрүүдийг үүсгэхийг шаарддаг. Учир нь гэр бүл 2 ганц хүүхэдтэй, na.rm = TRUE 2-р гэр бүл гаралтад нэг эгнээтэй байх баталгаа.

Огнооны хүрээг уртаас өргөн формат руу хөрвүүлэх

pivot_wider() - урвуу хувиргалт бөгөөд эсрэгээр нь мөрийн тоог багасгах замаар огнооны хүрээний баганын тоог нэмэгдүүлдэг.

R багц tidyr болон түүний шинэ функцууд илүү урт ба pivot_wider

Өгөгдлийг үнэн зөв хэлбэрт оруулахын тулд энэ төрлийн хувиргалтыг маш ховор ашигладаг боловч энэ техник нь танилцуулгад ашигладаг пивот хүснэгт үүсгэх эсвэл бусад хэрэгслүүдтэй нэгтгэхэд тустай байж болно.

Үнэндээ функцууд pivot_longer() и pivot_wider() тэгш хэмтэй бөгөөд бие биенээсээ урвуу үйлдлийг үүсгэдэг, өөрөөр хэлбэл: df %>% pivot_longer(spec = spec) %>% pivot_wider(spec = spec) и df %>% pivot_wider(spec = spec) %>% pivot_longer(spec = spec) анхны df-г буцаана.

Хүснэгтийг өргөн формат руу хөрвүүлэх хамгийн энгийн жишээ

Функц хэрхэн ажилладагийг харуулахын тулд pivot_wider() Бид өгөгдлийн багцыг ашиглах болно загасны_уулзалт, өөр өөр станцууд голын дагуух загасны хөдөлгөөнийг хэрхэн бүртгэдэг тухай мэдээллийг хадгалдаг.

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

Ихэнх тохиолдолд, хэрэв та станц бүрийн мэдээллийг тусдаа баганад оруулбал энэ хүснэгт илүү мэдээлэлтэй бөгөөд ашиглахад хялбар байх болно.

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>

Энэ өгөгдлийн багц нь зөвхөн станцаас загас илрүүлсэн үеийн мэдээллийг бүртгэдэг. хэрэв ямар нэгэн загасыг ямар нэгэн станц бүртгээгүй бол энэ мэдээлэл хүснэгтэд байхгүй болно. Энэ нь гаралтыг NA-аар дүүргэнэ гэсэн үг юм.

Гэсэн хэдий ч, энэ тохиолдолд бичлэг байхгүй байгаа нь загас хараагүй гэсэн үг гэдгийг бид мэдэж байгаа тул аргументыг ашиглаж болно. утгыг_бөглөх функцэд pivot_wider() мөн эдгээр дутуу утгыг тэгээр дүүргэ:

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>

Олон эх үүсвэрийн хувьсагчаас баганын нэрийг үүсгэх

Бидэнд бүтээгдэхүүн, улс, жилийн хослолыг агуулсан хүснэгт байна гэж төсөөлөөд үз дээ. Туршилтын огнооны хүрээ үүсгэхийн тулд та дараах кодыг ажиллуулж болно.

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

Бидний даалгавар бол өгөгдлийн хүрээг өргөжүүлэх бөгөөд ингэснээр нэг баганад бүтээгдэхүүн, улс орны хослол бүрийн өгөгдлийг агуулсан болно. Үүнийг хийхийн тулд аргументыг дамжуулаарай нэрс нэгтгэх талбаруудын нэрийг агуулсан вектор.

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

Та мөн функцэд техникийн үзүүлэлтүүдийг хэрэглэж болно pivot_wider(). Харин ирүүлсэн үед pivot_wider() тодорхойлолт нь эсрэгээр хувиргадаг pivot_longer():-д заасан баганууд .Нэр, утгыг ашиглан .утга болон бусад баганууд.

Энэ өгөгдлийн багцын хувьд, хэрэв та зөвхөн өгөгдөлд байгаа улс орнууд болон бүтээгдэхүүний хослолыг өөрийн гэсэн баганатай байлгахыг хүсвэл тусгайлсан тодорхойлолт үүсгэж болно:

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 үзэл баримтлалтай ажиллах хэд хэдэн дэвшилтэт жишээ

Жишээ болгон АНУ-ын хүн амын тооллогын орлого, түрээсийн мэдээллийн багцыг ашиглан өгөгдлийг цэвэрлэх.

Өгөгдлийн багц бидний_түрээсийн_орлого 2017 оны АНУ-ын муж бүрийн дундаж орлого, түрээсийн мэдээллийг агуулсан (мэдээлэл багцад байгаа эмх цэгцтэй тооллого).

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

Өгөгдлийн багцад өгөгдөл хадгалагдах хэлбэрээр бидний_түрээсийн_орлого Тэдэнтэй ажиллах нь туйлын тохиромжгүй тул бид багана бүхий өгөгдлийн багц үүсгэхийг хүсч байна: түрээс, түрээслэх, ирж, орлого_мэй. Энэ тодорхойлолтыг бий болгох олон арга бий, гэхдээ гол зүйл бол бид хувьсах хэмжигдэхүүний хослол бүрийг үүсгэх хэрэгтэй. тооцоо/мэйдараа нь баганын нэрийг үүсгэнэ.

  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

Энэ тодорхойлолтыг өгч байна pivot_wider() Бидний хайж буй үр дүнг бидэнд өгдөг:

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

Дэлхийн банк

Заримдаа өгөгдлийн багцыг хүссэн хэлбэрт оруулах нь хэд хэдэн алхам шаарддаг.
Өгөгдлийн багц дэлхийн_банкны_поп 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>

Бидний зорилго бол хувьсагч бүрийг өөрийн баганад багтаасан цэвэр өгөгдлийн багц үүсгэх явдал юм. Яг ямар алхмууд шаардлагатай байгаа нь тодорхойгүй байгаа ч бид хамгийн тодорхой асуудлаас эхлэх болно: жил нь олон баганаар тархсан байдаг.

Үүнийг засахын тулд та функцийг ашиглах хэрэгтэй 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

Дараагийн алхам бол индикаторын хувьсагчийг харах явдал юм.
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

SP.POP.GROW нь хүн амын өсөлт, SP.POP.TOTL нь нийт хүн ам, SP.URB. * ижил зүйл, гэхдээ зөвхөн хот суурин газрын хувьд. Эдгээр утгыг хоёр хувьсагч болгон хувааж үзье: газар нутаг - газар нутаг (нийт эсвэл хот) болон бодит өгөгдлийг агуулсан хувьсагч (хүн ам, өсөлт):

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

Одоо бидний хийх ёстой зүйл бол хувьсагчийг хоёр баганад хуваах явдал юм:

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

Харилцагчдын жагсаалт

Сүүлийн нэг жишээ дурдахад, танд вэбсайтаас хуулж, буулгасан харилцагчийн жагсаалт байна гэж төсөөлөөд үз дээ:

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

Энэ жагсаалтыг хүснэгтэд оруулах нь нэлээд хэцүү байдаг, учир нь аль өгөгдөл нь аль харилцагчид хамаарахыг тодорхойлох хувьсагч байхгүй. Бид шинэ харилцагчийн өгөгдөл "нэр"-ээр эхэлдэг тул талбарын баганад "нэр" гэсэн утгыг агуулж байх бүрт өвөрмөц танигч үүсгэж, нэгээр нэмэгдүүлэх боломжтой гэдгийг тэмдэглэснээр бид үүнийг засаж болно.

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

Одоо бид харилцагч бүрт өвөрмөц ID-тай болсон тул талбар болон утгыг багана болгон хувиргаж болно:

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>

дүгнэлт

Миний хувийн бодол бол шинэ үзэл баримтлал эмх цэгцтэй үнэхээр илүү мэдрэмжтэй, үйл ажиллагааны хувьд хуучин функцүүдээс хамаагүй давуу юм spread() и gather(). Энэ нийтлэл танд асуудлыг шийдвэрлэхэд тусалсан гэж найдаж байна pivot_longer() и pivot_wider().

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх