ื”ืจื—ื‘ืช ืขืžื•ื“ื•ืช ืžืงื•ื ื ื•ืช - ืจืฉื™ืžื•ืช ื‘ืืžืฆืขื•ืช ืฉืคืช R (ื—ื‘ื™ืœืช tidyr ื•ืคื•ื ืงืฆื™ื•ืช ืฉืœ ืžืฉืคื—ืช ื”-unnest)

ื‘ืจื•ื‘ ื”ืžืงืจื™ื, ื›ืืฉืจ ืขื•ื‘ื“ื™ื ืขื ืชื’ื•ื‘ื” ืฉื”ืชืงื‘ืœื” ืž-API, ืื• ืขื ื›ืœ ื ืชื•ืŸ ืื—ืจ ืฉื™ืฉ ืœื• ืžื‘ื ื” ืขืฅ ืžื•ืจื›ื‘, ืืชื” ืžืชืžื•ื“ื“ ืขื ืคื•ืจืžื˜ื™ื ืฉืœ JSON ื•-XML.

ืœืคื•ืจืžื˜ื™ื ื”ืœืœื• ื™ืฉ ื™ืชืจื•ื ื•ืช ืจื‘ื™ื: ื”ื ืžืื—ืกื ื™ื ื ืชื•ื ื™ื ื‘ืฆื•ืจื” ืงื•ืžืคืงื˜ื™ืช ืœืžื“ื™ ื•ืžืืคืฉืจื™ื ืœืžื ื•ืข ืฉื›ืคื•ืœ ืžื™ื“ืข ืžื™ื•ืชืจ.

ื”ื—ื™ืกืจื•ืŸ ืฉืœ ืคื•ืจืžื˜ื™ื ืืœื” ื”ื•ื ืžื•ืจื›ื‘ื•ืช ื”ืขื™ื‘ื•ื“ ื•ื”ื ื™ืชื•ื— ืฉืœื”ื. ืœื ื ื™ืชืŸ ืœื”ืฉืชืžืฉ ื‘ื ืชื•ื ื™ื ืœื ืžื•ื‘ื ื™ื ื‘ื—ื™ืฉื•ื‘ื™ื ื•ืœื ื ื™ืชืŸ ืœื‘ื ื•ืช ืขืœื™ื”ื ื”ื“ืžื™ื”.

ื”ืจื—ื‘ืช ืขืžื•ื“ื•ืช ืžืงื•ื ื ื•ืช - ืจืฉื™ืžื•ืช ื‘ืืžืฆืขื•ืช ืฉืคืช R (ื—ื‘ื™ืœืช tidyr ื•ืคื•ื ืงืฆื™ื•ืช ืฉืœ ืžืฉืคื—ืช ื”-unnest)

ืžืืžืจ ื–ื” ื”ื•ื ื”ืžืฉืš ื”ื’ื™ื•ื ื™ ืฉืœ ื”ืคืจืกื•ื "ื—ื‘ื™ืœืช R tidyr ื•ื”ืคื•ื ืงืฆื™ื•ืช ื”ื—ื“ืฉื•ืช ืฉืœื” pivot_longer ื•-pivot_wider". ื–ื” ื™ืขื–ื•ืจ ืœืš ืœื”ื‘ื™ื ืžื‘ื ื™ ื ืชื•ื ื™ื ืœื ืžื•ื‘ื ื™ื ืœืฆื•ืจืช ื˜ื‘ืœื” ืžื•ื›ืจืช ื•ืžืชืื™ืžื” ืœื ื™ืชื•ื— ื‘ืืžืฆืขื•ืช ื”ื—ื‘ื™ืœื” tidyr, ื”ื›ืœื•ืœื™ื ื‘ืœื™ื‘ืช ื”ืกืคืจื™ื™ื” tidyverse, ื•ืžืฉืคื—ืช ื”ืคื•ื ืงืฆื™ื•ืช ืฉืœื• unnest_*().

ืชื•ื›ืŸ

ืื ืืชื” ืžืขื•ื ื™ื™ืŸ ื‘ื ื™ืชื•ื— ื ืชื•ื ื™ื, ืื•ืœื™ ืืชื” ืžืขื•ื ื™ื™ืŸ ื‘- ืฉืœื™ ืžื‘ืจืง ะธ YouTube ืขืจื•ืฆื™ื. ืจื•ื‘ ื”ืชื•ื›ืŸ ืžื•ืงื“ืฉ ืœืฉืคืช R.

  1. ืžื‘ื•ื
  2. ืžืฉืชืžืฉื™ GitHub
  3. ืžืื’ืจื™ Github
  4. ื“ืžื•ื™ื•ืช ืžืฉื—ืงื™ ื”ื›ืก
  5. ืงื™ื“ื•ื“ ื’ื™ืื•ื’ืจืคื™ ืขื ื’ื•ื’ืœ
  6. ื“ื™ืกืงื•ื’ืจืคื™ื” ืฉืœ ืฉืจืœื” ื’ืœืคื ื“
  7. ืžืกืงื ื”

ืžื‘ื•ื

ืžืœื‘ืŸ (ื”ืขืจืช ื”ืžืชืจื’ื, ืœื ืžืฆืืชื™ ืืคืฉืจื•ื™ื•ืช ืชืจื’ื•ื ืžืชืื™ืžื•ืช ืœืžื•ื ื— ื”ื–ื”, ืื– ื ืฉืื™ืจ ืื•ืชื• ื›ืžื• ืฉื”ื•ื.) ื”ื•ื ืชื”ืœื™ืš ื”ื‘ืืช ื ืชื•ื ื™ื ืœื ืžื•ื‘ื ื™ื ืขื ืžืขืจื›ื™ื ืžืงื•ื ื ื™ื ืœื˜ื‘ืœื” ื“ื• ืžื™ืžื“ื™ืช ื”ืžื•ืจื›ื‘ืช ืžืฉื•ืจื•ืช ื•ืขืžื•ื“ื•ืช ืžื•ื›ืจื•ืช. IN tidyr ื™ืฉื ืŸ ืžืกืคืจ ืคื•ื ืงืฆื™ื•ืช ืฉื™ืขื–ืจื• ืœืš ืœื”ืจื—ื™ื‘ ืืช ืขืžื•ื“ื•ืช ื”ืจืฉื™ืžื” ื”ืžืงื•ื ื ื•ืช ื•ืœื”ืงื˜ื™ืŸ ืืช ื”ื ืชื•ื ื™ื ืœืฆื•ืจื” ืžืœื‘ื ื™ืช ื•ื˜ื‘ืœื”:

  • unnest_longer() ืœื•ืงื— ื›ืœ ืจื›ื™ื‘ ื‘ืจืฉื™ืžืช ื”ืขืžื•ื“ื•ืช ื•ื™ื•ืฆืจ ืฉื•ืจื” ื—ื“ืฉื”.
  • unnest_wider() ืœื•ืงื— ื›ืœ ืจื›ื™ื‘ ื‘ืจืฉื™ืžืช ื”ืขืžื•ื“ื•ืช ื•ื™ื•ืฆืจ ืขืžื•ื“ื” ื—ื“ืฉื”.
  • unnest_auto() ืงื•ื‘ืข ืื•ื˜ื•ืžื˜ื™ืช ื‘ืื™ื–ื• ืคื•ื ืงืฆื™ื” ื”ื›ื™ ื›ื“ืื™ ืœื”ืฉืชืžืฉ
    unnest_longer() ืื• unnest_wider().
  • hoist() ื“ื•ืžื” ืœ unnest_wider() ืื‘ืœ ื‘ื•ื—ืจ ืจืง ืืช ื”ืจื›ื™ื‘ื™ื ืฉืฆื•ื™ื ื• ื•ืžืืคืฉืจ ืœืš ืœืขื‘ื•ื“ ืขื ืžืกืคืจ ืจืžื•ืช ืฉืœ ืงื™ื ื•ืŸ.

ื ื™ืชืŸ ืœืคืชื•ืจ ืืช ืจื•ื‘ ื”ื‘ืขื™ื•ืช ื”ืงืฉื•ืจื•ืช ื‘ื”ื‘ืืช ื ืชื•ื ื™ื ืœื ืžื•ื‘ื ื™ื ืขื ืžืกืคืจ ืจืžื•ืช ืฉืœ ืงื™ื ื•ืŸ ืœื˜ื‘ืœื” ื“ื• ืžื™ืžื“ื™ืช ืขืœ ื™ื“ื™ ืฉื™ืœื•ื‘ ื”ืคื•ื ืงืฆื™ื•ืช ื”ืžืคื•ืจื˜ื•ืช ืขื dplyr.

ื›ื“ื™ ืœื”ื“ื’ื™ื ืืช ื”ื˜ื›ื ื™ืงื•ืช ื”ืœืœื•, ื ืฉืชืžืฉ ื‘ื—ื‘ื™ืœื” repurrrsive, ื”ืžืกืคืง ืจืฉื™ืžื•ืช ืžื•ืจื›ื‘ื•ืช ืžืจื•ื‘ื•ืช ืจืžื•ืช ื”ื ื’ื–ืจื•ืช ืž-API ืื™ื ื˜ืจื ื˜.

library(tidyr)
library(dplyr)
library(repurrrsive)

ืžืฉืชืžืฉื™ GitHub

ื‘ื•ืื• ื ืชื—ื™ืœ ืขื gh_users, ืจืฉื™ืžื” ื”ืžื›ื™ืœื” ืžื™ื“ืข ืขืœ ืฉื™ืฉื” ืžืฉืชืžืฉื™ GitHub. ืจืืฉื™ืช ื‘ื•ืื• ื ืฉื ื” ืืช ื”ืจืฉื™ืžื” gh_users ะฒ ื˜ื‘ืœ ืžึดืกื’ึถืจึถืช:

users <-   tibble( user = gh_users ) 

ื–ื” ื ืจืื” ืงืฆืช ืžื ื•ื’ื“ ืœืื™ื ื˜ื•ืื™ืฆื™ื”: ืœืžื” ืœืกืคืง ืจืฉื™ืžื” gh_users, ืœืžื‘ื ื” ื ืชื•ื ื™ื ืžื•ืจื›ื‘ ื™ื•ืชืจ? ืื‘ืœ ืœืžืกื’ืจืช ื ืชื•ื ื™ื ื™ืฉ ื™ืชืจื•ืŸ ื’ื“ื•ืœ: ื”ื™ื ืžืฉืœื‘ืช ื•ืงื˜ื•ืจื™ื ืžืจื•ื‘ื™ื ื›ืš ืฉื”ื›ืœ ื ืžืฆื ื‘ืžืขืงื‘ ื‘ืื•ื‘ื™ื™ืงื˜ ืื—ื“.

ื›ืœ ืจื›ื™ื‘ ืื•ื‘ื™ื™ืงื˜ users ื”ื™ื ืจืฉื™ืžื” ื‘ืขืœืช ืฉื ืฉื‘ื” ื›ืœ ืจื›ื™ื‘ ืžื™ื™ืฆื’ ืขืžื•ื“ื”.

names(users$user[[1]])
#>  [1] "login"               "id"                  "avatar_url"         
#>  [4] "gravatar_id"         "url"                 "html_url"           
#>  [7] "followers_url"       "following_url"       "gists_url"          
#> [10] "starred_url"         "subscriptions_url"   "organizations_url"  
#> [13] "repos_url"           "events_url"          "received_events_url"
#> [16] "type"                "site_admin"          "name"               
#> [19] "company"             "blog"                "location"           
#> [22] "email"               "hireable"            "bio"                
#> [25] "public_repos"        "public_gists"        "followers"          
#> [28] "following"           "created_at"          "updated_at"

ื™ืฉื ืŸ ืฉืชื™ ื“ืจื›ื™ื ืœื”ืคื•ืš ืจื›ื™ื‘ื™ ืจืฉื™ืžื” ืœืขืžื•ื“ื•ืช. unnest_wider() ืœื•ืงื— ื›ืœ ืจื›ื™ื‘ ื•ื™ื•ืฆืจ ืขืžื•ื“ื” ื—ื“ืฉื”:

users %>% unnest_wider(user)
#> # A tibble: 6 x 30
#>   login     id avatar_url gravatar_id url   html_url followers_url
#>   <chr>  <int> <chr>      <chr>       <chr> <chr>    <chr>        
#> 1 gaboโ€ฆ 6.60e5 https://aโ€ฆ ""          httpโ€ฆ https:/โ€ฆ https://api.โ€ฆ
#> 2 jennโ€ฆ 5.99e5 https://aโ€ฆ ""          httpโ€ฆ https:/โ€ฆ https://api.โ€ฆ
#> 3 jtleโ€ฆ 1.57e6 https://aโ€ฆ ""          httpโ€ฆ https:/โ€ฆ https://api.โ€ฆ
#> 4 juliโ€ฆ 1.25e7 https://aโ€ฆ ""          httpโ€ฆ https:/โ€ฆ https://api.โ€ฆ
#> 5 leepโ€ฆ 3.51e6 https://aโ€ฆ ""          httpโ€ฆ https:/โ€ฆ https://api.โ€ฆ
#> 6 masaโ€ฆ 8.36e6 https://aโ€ฆ ""          httpโ€ฆ https:/โ€ฆ https://api.โ€ฆ
#> # โ€ฆ with 23 more variables: following_url <chr>, gists_url <chr>,
#> #   starred_url <chr>, subscriptions_url <chr>, organizations_url <chr>,
#> #   repos_url <chr>, events_url <chr>, received_events_url <chr>,
#> #   type <chr>, site_admin <lgl>, name <chr>, company <chr>, blog <chr>,
#> #   location <chr>, email <chr>, public_repos <int>, public_gists <int>,
#> #   followers <int>, following <int>, created_at <chr>, updated_at <chr>,
#> #   bio <chr>, hireable <lgl>

ื‘ืžืงืจื” ื–ื”, ื™ืฉ ืœื ื• ื˜ื‘ืœื” ื”ืžื•ืจื›ื‘ืช ืž-30 ืขืžื•ื“ื•ืช, ื•ืœื ื ืฆื˜ืจืš ืืช ืจื•ื‘ืŸ, ืื– ื ื•ื›ืœ ื‘ืžืงื•ื ื–ืืช unnest_wider() ืฉื™ืžื•ืฉ hoist(). hoist() ืžืืคืฉืจ ืœื ื• ืœื—ืœืฅ ืจื›ื™ื‘ื™ื ื ื‘ื—ืจื™ื ื‘ืืžืฆืขื•ืช ืื•ืชื• ืชื—ื‘ื™ืจ ื›ืžื• purrr::pluck():

users %>% hoist(user, 
  followers = "followers", 
  login = "login", 
  url = "html_url"
)
#> # A tibble: 6 x 4
#>   followers login       url                            user             
#>       <int> <chr>       <chr>                          <list>           
#> 1       303 gaborcsardi https://github.com/gaborcsardi <named list [27]>
#> 2       780 jennybc     https://github.com/jennybc     <named list [27]>
#> 3      3958 jtleek      https://github.com/jtleek      <named list [27]>
#> 4       115 juliasilge  https://github.com/juliasilge  <named list [27]>
#> 5       213 leeper      https://github.com/leeper      <named list [27]>
#> 6        34 masalmon    https://github.com/masalmon    <named list [27]>

hoist() ืžืกื™ืจ ืืช ื”ืจื›ื™ื‘ื™ื ื‘ืขืœื™ ื”ืฉื ืฉืฆื•ื™ื ื• ืžืจืฉื™ืžืช ืขืžื•ื“ื•ืช ื”ืžืฉืชืžืฉืื– ืืชื” ื™ื›ื•ืœ ืœืฉืงื•ืœ hoist() ื›ืžื• ื”ืขื‘ืจืช ืจื›ื™ื‘ื™ื ืžื”ืจืฉื™ืžื” ื”ืคื ื™ืžื™ืช ืฉืœ ืžืกื’ืจืช ืชืืจื™ืš ืœืจืžื” ื”ืขืœื™ื•ื ื” ืฉืœื”.

ืžืื’ืจื™ Github

ื™ื™ืฉื•ืจ ืจืฉื™ืžื” gh_repos ืื ื• ืžืชื—ื™ืœื™ื ื‘ืื•ืคืŸ ื“ื•ืžื” ืขืœ ื™ื“ื™ ื”ืžืจืชื• ืœ tibble:

repos <- tibble(repo = gh_repos)
repos
#> # A tibble: 6 x 1
#>   repo       
#>   <list>     
#> 1 <list [30]>
#> 2 <list [30]>
#> 3 <list [30]>
#> 4 <list [26]>
#> 5 <list [30]>
#> 6 <list [30]>

ื”ืคืขื ื”ืืœืžื ื˜ื™ื ื”ืžืฉืชืžืฉ ืžื™ื™ืฆื’ื™ื ืจืฉื™ืžื” ืฉืœ ืžืื’ืจื™ื ื‘ื‘ืขืœื•ืช ืžืฉืชืžืฉ ื–ื”. ื›ืœ ืžืื’ืจ ื”ื•ื ืชืฆืคื™ืช ื ืคืจื“ืช, ื›ืš ืœืคื™ ื”ืจืขื™ื•ืŸ ืฉืœ ื ืชื•ื ื™ื ืžืกื•ื“ืจื™ื (ื‘ืขืจืš ื ืชื•ื ื™ื ืžืกื•ื“ืจื™ื) ื”ื ืฆืจื™ื›ื™ื ืœื”ืคื•ืš ืœืฉื•ืจื•ืช ื—ื“ืฉื•ืช, ื•ื–ื• ื”ืกื™ื‘ื” ืฉืื ื• ืžืฉืชืžืฉื™ื unnest_longer() ื•ืœื unnest_wider():

repos <- repos %>% unnest_longer(repo)
repos
#> # A tibble: 176 x 1
#>    repo             
#>    <list>           
#>  1 <named list [68]>
#>  2 <named list [68]>
#>  3 <named list [68]>
#>  4 <named list [68]>
#>  5 <named list [68]>
#>  6 <named list [68]>
#>  7 <named list [68]>
#>  8 <named list [68]>
#>  9 <named list [68]>
#> 10 <named list [68]>
#> # โ€ฆ with 166 more rows

ืขื›ืฉื™ื• ืื ื—ื ื• ื™ื›ื•ืœื™ื ืœื”ืฉืชืžืฉ unnest_wider() ืื• hoist() :

repos %>% hoist(repo, 
  login = c("owner", "login"), 
  name = "name",
  homepage = "homepage",
  watchers = "watchers_count"
)
#> # A tibble: 176 x 5
#>    login       name        homepage watchers repo             
#>    <chr>       <chr>       <chr>       <int> <list>           
#>  1 gaborcsardi after       <NA>            5 <named list [65]>
#>  2 gaborcsardi argufy      <NA>           19 <named list [65]>
#>  3 gaborcsardi ask         <NA>            5 <named list [65]>
#>  4 gaborcsardi baseimports <NA>            0 <named list [65]>
#>  5 gaborcsardi citest      <NA>            0 <named list [65]>
#>  6 gaborcsardi clisymbols  ""             18 <named list [65]>
#>  7 gaborcsardi cmaker      <NA>            0 <named list [65]>
#>  8 gaborcsardi cmark       <NA>            0 <named list [65]>
#>  9 gaborcsardi conditions  <NA>            0 <named list [65]>
#> 10 gaborcsardi crayon      <NA>           52 <named list [65]>
#> # โ€ฆ with 166 more rows

ืฉื™ืžื• ืœื‘ ืœืฉื™ืžื•ืฉ c("owner", "login"): ื–ื” ืžืืคืฉืจ ืœื ื• ืœืงื‘ืœ ืืช ืขืจืš ื”ืจืžื” ื”ืฉื ื™ื™ื” ืžืจืฉื™ืžื” ืžืงื•ื ื ืช owner. ื’ื™ืฉื” ื—ืœื•ืคื™ืช ื”ื™ื ืœืงื‘ืœ ืืช ื›ืœ ื”ืจืฉื™ืžื” owner ื•ืœืื—ืจ ืžื›ืŸ ื‘ืืžืฆืขื•ืช ื”ืคื•ื ืงืฆื™ื” unnest_wider() ืฉื™ื ื›ืœ ืื—ื“ ืžื”ืจื›ื™ื‘ื™ื ืฉืœื• ื‘ืขืžื•ื“ื”:

repos %>% 
  hoist(repo, owner = "owner") %>% 
  unnest_wider(owner)
#> # A tibble: 176 x 18
#>    login     id avatar_url gravatar_id url   html_url followers_url
#>    <chr>  <int> <chr>      <chr>       <chr> <chr>    <chr>        
#>  1 gaboโ€ฆ 660288 https://aโ€ฆ ""          httpโ€ฆ https:/โ€ฆ https://api.โ€ฆ
#>  2 gaboโ€ฆ 660288 https://aโ€ฆ ""          httpโ€ฆ https:/โ€ฆ https://api.โ€ฆ
#>  3 gaboโ€ฆ 660288 https://aโ€ฆ ""          httpโ€ฆ https:/โ€ฆ https://api.โ€ฆ
#>  4 gaboโ€ฆ 660288 https://aโ€ฆ ""          httpโ€ฆ https:/โ€ฆ https://api.โ€ฆ
#>  5 gaboโ€ฆ 660288 https://aโ€ฆ ""          httpโ€ฆ https:/โ€ฆ https://api.โ€ฆ
#>  6 gaboโ€ฆ 660288 https://aโ€ฆ ""          httpโ€ฆ https:/โ€ฆ https://api.โ€ฆ
#>  7 gaboโ€ฆ 660288 https://aโ€ฆ ""          httpโ€ฆ https:/โ€ฆ https://api.โ€ฆ
#>  8 gaboโ€ฆ 660288 https://aโ€ฆ ""          httpโ€ฆ https:/โ€ฆ https://api.โ€ฆ
#>  9 gaboโ€ฆ 660288 https://aโ€ฆ ""          httpโ€ฆ https:/โ€ฆ https://api.โ€ฆ
#> 10 gaboโ€ฆ 660288 https://aโ€ฆ ""          httpโ€ฆ https:/โ€ฆ https://api.โ€ฆ
#> # โ€ฆ with 166 more rows, and 11 more variables: following_url <chr>,
#> #   gists_url <chr>, starred_url <chr>, subscriptions_url <chr>,
#> #   organizations_url <chr>, repos_url <chr>, events_url <chr>,
#> #   received_events_url <chr>, type <chr>, site_admin <lgl>, repo <list>

ื‘ืžืงื•ื ืœื—ืฉื•ื‘ ืขืœ ื‘ื—ื™ืจืช ื”ืคื•ื ืงืฆื™ื” ื”ื ื›ื•ื ื” unnest_longer() ืื• unnest_wider() ืืชื” ื™ื›ื•ืœ ืœื”ืฉืชืžืฉ unnest_auto(). ืคื•ื ืงืฆื™ื” ื–ื• ืžืฉืชืžืฉืช ื‘ืžืกืคืจ ืฉื™ื˜ื•ืช ื”ื™ื•ืจื™ืกื˜ื™ื•ืช ื›ื“ื™ ืœื‘ื—ื•ืจ ืืช ื”ืคื•ื ืงืฆื™ื” ื”ืžืชืื™ืžื” ื‘ื™ื•ืชืจ ืœื”ืžืจืช ื”ื ืชื•ื ื™ื, ื•ืžืฆื™ื’ื” ื”ื•ื“ืขื” ืขืœ ื”ืฉื™ื˜ื” ืฉื ื‘ื—ืจื”.

tibble(repo = gh_repos) %>% 
  unnest_auto(repo) %>% 
  unnest_auto(repo)
#> Using `unnest_longer(repo)`; no element has names
#> Using `unnest_wider(repo)`; elements have 68 names in common
#> # A tibble: 176 x 67
#>        id name  full_name owner private html_url description fork  url  
#>     <int> <chr> <chr>     <lis> <lgl>   <chr>    <chr>       <lgl> <chr>
#>  1 6.12e7 after gaborcsaโ€ฆ <namโ€ฆ FALSE   https:/โ€ฆ Run Code iโ€ฆ FALSE httpโ€ฆ
#>  2 4.05e7 arguโ€ฆ gaborcsaโ€ฆ <namโ€ฆ FALSE   https:/โ€ฆ Declarativโ€ฆ FALSE httpโ€ฆ
#>  3 3.64e7 ask   gaborcsaโ€ฆ <namโ€ฆ FALSE   https:/โ€ฆ Friendly Cโ€ฆ FALSE httpโ€ฆ
#>  4 3.49e7 baseโ€ฆ gaborcsaโ€ฆ <namโ€ฆ FALSE   https:/โ€ฆ Do we get โ€ฆ FALSE httpโ€ฆ
#>  5 6.16e7 citeโ€ฆ gaborcsaโ€ฆ <namโ€ฆ FALSE   https:/โ€ฆ Test R pacโ€ฆ TRUE  httpโ€ฆ
#>  6 3.39e7 clisโ€ฆ gaborcsaโ€ฆ <namโ€ฆ FALSE   https:/โ€ฆ Unicode syโ€ฆ FALSE httpโ€ฆ
#>  7 3.72e7 cmakโ€ฆ gaborcsaโ€ฆ <namโ€ฆ FALSE   https:/โ€ฆ port of cmโ€ฆ TRUE  httpโ€ฆ
#>  8 6.80e7 cmark gaborcsaโ€ฆ <namโ€ฆ FALSE   https:/โ€ฆ CommonMarkโ€ฆ TRUE  httpโ€ฆ
#>  9 6.32e7 condโ€ฆ gaborcsaโ€ฆ <namโ€ฆ FALSE   https:/โ€ฆ <NA>        TRUE  httpโ€ฆ
#> 10 2.43e7 crayโ€ฆ gaborcsaโ€ฆ <namโ€ฆ FALSE   https:/โ€ฆ R package โ€ฆ FALSE httpโ€ฆ
#> # โ€ฆ with 166 more rows, and 58 more variables: forks_url <chr>,
#> #   keys_url <chr>, collaborators_url <chr>, teams_url <chr>,
#> #   hooks_url <chr>, issue_events_url <chr>, events_url <chr>,
#> #   assignees_url <chr>, branches_url <chr>, tags_url <chr>,
#> #   blobs_url <chr>, git_tags_url <chr>, git_refs_url <chr>,
#> #   trees_url <chr>, statuses_url <chr>, languages_url <chr>,
#> #   stargazers_url <chr>, contributors_url <chr>, subscribers_url <chr>,
#> #   subscription_url <chr>, commits_url <chr>, git_commits_url <chr>,
#> #   comments_url <chr>, issue_comment_url <chr>, contents_url <chr>,
#> #   compare_url <chr>, merges_url <chr>, archive_url <chr>,
#> #   downloads_url <chr>, issues_url <chr>, pulls_url <chr>,
#> #   milestones_url <chr>, notifications_url <chr>, labels_url <chr>,
#> #   releases_url <chr>, deployments_url <chr>, created_at <chr>,
#> #   updated_at <chr>, pushed_at <chr>, git_url <chr>, ssh_url <chr>,
#> #   clone_url <chr>, svn_url <chr>, size <int>, stargazers_count <int>,
#> #   watchers_count <int>, language <chr>, has_issues <lgl>,
#> #   has_downloads <lgl>, has_wiki <lgl>, has_pages <lgl>,
#> #   forks_count <int>, open_issues_count <int>, forks <int>,
#> #   open_issues <int>, watchers <int>, default_branch <chr>,
#> #   homepage <chr>

ื“ืžื•ื™ื•ืช ืžืฉื—ืงื™ ื”ื›ืก

got_chars ื‘ืขืœ ืžื‘ื ื” ื–ื”ื” ืœ gh_users: ื–ื•ื”ื™ ืงื‘ื•ืฆื” ืฉืœ ืจืฉื™ืžื•ืช ืขื ืฉื, ื›ืืฉืจ ื›ืœ ืจื›ื™ื‘ ื‘ืจืฉื™ืžื” ื”ืคื ื™ืžื™ืช ืžืชืืจ ืชื›ื•ื ื” ื›ืœืฉื”ื™ ืฉืœ ื“ืžื•ืช ืžืฉื—ืงื™ ื”ื›ืก. ืžื‘ื™ื got_chars ืขื‘ื•ืจ ืชืฆื•ื’ืช ื”ื˜ื‘ืœื”, ืื ื• ืžืชื—ื™ืœื™ื ื‘ื™ืฆื™ืจืช ืžืกื’ืจืช ืชืืจื™ืš, ื‘ื“ื™ื•ืง ื›ืžื• ื‘ื“ื•ื’ืžืื•ืช ื”ืงื•ื“ืžื•ืช, ื•ืœืื—ืจ ืžื›ืŸ ืžืžื™ืจื™ื ื›ืœ ืืœืžื ื˜ ืœืขืžื•ื“ื” ื ืคืจื“ืช:

chars <- tibble(char = got_chars)
chars
#> # A tibble: 30 x 1
#>    char             
#>    <list>           
#>  1 <named list [18]>
#>  2 <named list [18]>
#>  3 <named list [18]>
#>  4 <named list [18]>
#>  5 <named list [18]>
#>  6 <named list [18]>
#>  7 <named list [18]>
#>  8 <named list [18]>
#>  9 <named list [18]>
#> 10 <named list [18]>
#> # โ€ฆ with 20 more rows

chars2 <- chars %>% unnest_wider(char)
chars2
#> # A tibble: 30 x 18
#>    url      id name  gender culture born  died  alive titles aliases father
#>    <chr> <int> <chr> <chr>  <chr>   <chr> <chr> <lgl> <list> <list>  <chr> 
#>  1 httpโ€ฆ  1022 Theoโ€ฆ Male   Ironboโ€ฆ In 2โ€ฆ ""    TRUE  <chr โ€ฆ <chr [โ€ฆ ""    
#>  2 httpโ€ฆ  1052 Tyriโ€ฆ Male   ""      In 2โ€ฆ ""    TRUE  <chr โ€ฆ <chr [โ€ฆ ""    
#>  3 httpโ€ฆ  1074 Victโ€ฆ Male   Ironboโ€ฆ In 2โ€ฆ ""    TRUE  <chr โ€ฆ <chr [โ€ฆ ""    
#>  4 httpโ€ฆ  1109 Will  Male   ""      ""    In 2โ€ฆ FALSE <chr โ€ฆ <chr [โ€ฆ ""    
#>  5 httpโ€ฆ  1166 Areoโ€ฆ Male   Norvosโ€ฆ In 2โ€ฆ ""    TRUE  <chr โ€ฆ <chr [โ€ฆ ""    
#>  6 httpโ€ฆ  1267 Chett Male   ""      At Hโ€ฆ In 2โ€ฆ FALSE <chr โ€ฆ <chr [โ€ฆ ""    
#>  7 httpโ€ฆ  1295 Cresโ€ฆ Male   ""      In 2โ€ฆ In 2โ€ฆ FALSE <chr โ€ฆ <chr [โ€ฆ ""    
#>  8 httpโ€ฆ   130 Ariaโ€ฆ Female Dornish In 2โ€ฆ ""    TRUE  <chr โ€ฆ <chr [โ€ฆ ""    
#>  9 httpโ€ฆ  1303 Daenโ€ฆ Female Valyriโ€ฆ In 2โ€ฆ ""    TRUE  <chr โ€ฆ <chr [โ€ฆ ""    
#> 10 httpโ€ฆ  1319 Davoโ€ฆ Male   Westerโ€ฆ In 2โ€ฆ ""    TRUE  <chr โ€ฆ <chr [โ€ฆ ""    
#> # โ€ฆ with 20 more rows, and 7 more variables: mother <chr>, spouse <chr>,
#> #   allegiances <list>, books <list>, povBooks <list>, tvSeries <list>,
#> #   playedBy <list>

ืžื‘ื ื” got_chars ืงืฆืช ื™ื•ืชืจ ืงืฉื” ืž gh_users, ื›ื™ ื›ืžื” ืจื›ื™ื‘ื™ ืจืฉื™ืžื” char ืขืฆืžื ื”ื ืจืฉื™ืžื”, ื›ืชื•ืฆืื” ืžื›ืš ืื ื• ืžืงื‘ืœื™ื ืขืžื•ื“ื™ื - ืจืฉื™ืžื•ืช:

chars2 %>% select_if(is.list)
#> # A tibble: 30 x 7
#>    titles    aliases    allegiances books     povBooks  tvSeries  playedBy 
#>    <list>    <list>     <list>      <list>    <list>    <list>    <list>   
#>  1 <chr [3]> <chr [4]>  <chr [1]>   <chr [3]> <chr [2]> <chr [6]> <chr [1]>
#>  2 <chr [2]> <chr [11]> <chr [1]>   <chr [2]> <chr [4]> <chr [6]> <chr [1]>
#>  3 <chr [2]> <chr [1]>  <chr [1]>   <chr [3]> <chr [2]> <chr [1]> <chr [1]>
#>  4 <chr [1]> <chr [1]>  <???>       <chr [1]> <chr [1]> <chr [1]> <chr [1]>
#>  5 <chr [1]> <chr [1]>  <chr [1]>   <chr [3]> <chr [2]> <chr [2]> <chr [1]>
#>  6 <chr [1]> <chr [1]>  <???>       <chr [2]> <chr [1]> <chr [1]> <chr [1]>
#>  7 <chr [1]> <chr [1]>  <???>       <chr [2]> <chr [1]> <chr [1]> <chr [1]>
#>  8 <chr [1]> <chr [1]>  <chr [1]>   <chr [4]> <chr [1]> <chr [1]> <chr [1]>
#>  9 <chr [5]> <chr [11]> <chr [1]>   <chr [1]> <chr [4]> <chr [6]> <chr [1]>
#> 10 <chr [4]> <chr [5]>  <chr [2]>   <chr [1]> <chr [3]> <chr [5]> <chr [1]>
#> # โ€ฆ with 20 more rows

ื”ืคืขื•ืœื•ืช ื”ื ื•ืกืคื•ืช ืฉืœืš ืชืœื•ื™ื•ืช ื‘ืžื˜ืจื•ืช ื”ื ื™ืชื•ื—. ืื•ืœื™ ืืชื” ืฆืจื™ืš ืœืฉื™ื ืžื™ื“ืข ืขืœ ื”ืฉื•ืจื•ืช ืขื‘ื•ืจ ื›ืœ ืกืคืจ ื•ืกื“ืจื” ืฉื‘ื”ื ื”ื“ืžื•ืช ืžื•ืคื™ืขื”:

chars2 %>% 
  select(name, books, tvSeries) %>% 
  pivot_longer(c(books, tvSeries), names_to = "media", values_to = "value") %>% 
  unnest_longer(value)
#> # A tibble: 180 x 3
#>    name             media    value            
#>    <chr>            <chr>    <chr>            
#>  1 Theon Greyjoy    books    A Game of Thrones
#>  2 Theon Greyjoy    books    A Storm of Swords
#>  3 Theon Greyjoy    books    A Feast for Crows
#>  4 Theon Greyjoy    tvSeries Season 1         
#>  5 Theon Greyjoy    tvSeries Season 2         
#>  6 Theon Greyjoy    tvSeries Season 3         
#>  7 Theon Greyjoy    tvSeries Season 4         
#>  8 Theon Greyjoy    tvSeries Season 5         
#>  9 Theon Greyjoy    tvSeries Season 6         
#> 10 Tyrion Lannister books    A Feast for Crows
#> # โ€ฆ with 170 more rows

ืื• ืื•ืœื™ ืืชื” ืจื•ืฆื” ืœื™ืฆื•ืจ ื˜ื‘ืœื” ืฉืชืืคืฉืจ ืœืš ืœื”ืชืื™ื ืืช ื”ื“ืžื•ืช ื•ื”ื™ืฆื™ืจื”:

chars2 %>% 
  select(name, title = titles) %>% 
  unnest_longer(title)
#> # A tibble: 60 x 2
#>    name              title                                               
#>    <chr>             <chr>                                               
#>  1 Theon Greyjoy     Prince of Winterfell                                
#>  2 Theon Greyjoy     Captain of Sea Bitch                                
#>  3 Theon Greyjoy     Lord of the Iron Islands (by law of the green lands)
#>  4 Tyrion Lannister  Acting Hand of the King (former)                    
#>  5 Tyrion Lannister  Master of Coin (former)                             
#>  6 Victarion Greyjoy Lord Captain of the Iron Fleet                      
#>  7 Victarion Greyjoy Master of the Iron Victory                          
#>  8 Will              ""                                                  
#>  9 Areo Hotah        Captain of the Guard at Sunspear                    
#> 10 Chett             ""                                                  
#> # โ€ฆ with 50 more rows

(ืฉื™ื ืœื‘ ืœืขืจื›ื™ื ื”ืจื™ืงื™ื "" ื‘ืชื—ื•ื title, ื–ื” ื ื•ื‘ืข ืžืฉื’ื™ืื•ืช ืฉื ืขืฉื• ื‘ืขืช ื”ื–ื ืช ื ืชื•ื ื™ื got_chars: ืœืžืขืฉื”, ื“ืžื•ื™ื•ืช ืฉืื™ืŸ ืœื”ืŸ ื›ื•ืชืจื•ืช ืกืคืจ ื•ืกื“ืจื•ืช ื˜ืœื•ื•ื™ื–ื™ื” ืžืงื‘ื™ืœื•ืช ื‘ืชื—ื•ื title ื—ื™ื™ื‘ ืœื”ื™ื•ืช ื•ืงื˜ื•ืจ ื‘ืื•ืจืš 0, ืœื ื•ืงื˜ื•ืจ ื‘ืื•ืจืš 1 ื”ืžื›ื™ืœ ืืช ื”ืžื—ืจื•ื–ืช ื”ืจื™ืงื”.)

ืื ื• ื™ื›ื•ืœื™ื ืœืฉื›ืชื‘ ืืช ื”ื“ื•ื’ืžื” ืœืขื™ืœ ื‘ืืžืฆืขื•ืช ื”ืคื•ื ืงืฆื™ื” unnest_auto(). ื’ื™ืฉื” ื–ื• ื ื•ื—ื” ืœื ื™ืชื•ื— ื—ื“ ืคืขืžื™, ืืš ืื™ืŸ ืœื”ืกืชืžืš ืขืœื™ื” unnest_auto() ืœืฉื™ืžื•ืฉ ืขืœ ื‘ืกื™ืก ืงื‘ื•ืข. ื”ื ืงื•ื“ื” ื”ื™ื ืฉืื ืžื‘ื ื” ื”ื ืชื•ื ื™ื ืฉืœืš ืžืฉืชื ื” unnest_auto() ื™ื›ื•ืœ ืœืฉื ื•ืช ืืช ืžื ื’ื ื•ืŸ ื”ืžืจืช ื”ื ืชื•ื ื™ื ืฉื ื‘ื—ืจ ืื ื”ื•ื ื”ืจื—ื™ื‘ ืชื—ื™ืœื” ืขืžื•ื“ื•ืช ืจืฉื™ืžื” ืœืฉื•ืจื•ืช ื‘ืืžืฆืขื•ืช unnest_longer(), ืื– ื›ืืฉืจ ืžื‘ื ื” ื”ื ืชื•ื ื™ื ื”ื ื›ื ืกื™ื ืžืฉืชื ื”, ื ื™ืชืŸ ืœืฉื ื•ืช ืืช ื”ื”ื™ื’ื™ื•ืŸ ืœื˜ื•ื‘ืชื• unnest_wider(), ื•ืฉื™ืžื•ืฉ ื‘ื’ื™ืฉื” ื–ื• ื‘ืื•ืคืŸ ืฉื•ื˜ืฃ ืขืœื•ืœ ืœื”ื•ื‘ื™ืœ ืœืฉื’ื™ืื•ืช ื‘ืœืชื™ ืฆืคื•ื™ื•ืช.

tibble(char = got_chars) %>% 
  unnest_auto(char) %>% 
  select(name, title = titles) %>% 
  unnest_auto(title)
#> Using `unnest_wider(char)`; elements have 18 names in common
#> Using `unnest_longer(title)`; no element has names
#> # A tibble: 60 x 2
#>    name              title                                               
#>    <chr>             <chr>                                               
#>  1 Theon Greyjoy     Prince of Winterfell                                
#>  2 Theon Greyjoy     Captain of Sea Bitch                                
#>  3 Theon Greyjoy     Lord of the Iron Islands (by law of the green lands)
#>  4 Tyrion Lannister  Acting Hand of the King (former)                    
#>  5 Tyrion Lannister  Master of Coin (former)                             
#>  6 Victarion Greyjoy Lord Captain of the Iron Fleet                      
#>  7 Victarion Greyjoy Master of the Iron Victory                          
#>  8 Will              ""                                                  
#>  9 Areo Hotah        Captain of the Guard at Sunspear                    
#> 10 Chett             ""                                                  
#> # โ€ฆ with 50 more rows

ืงื™ื“ื•ื“ ื’ื™ืื•ื’ืจืคื™ ืขื ื’ื•ื’ืœ

ืœืื—ืจ ืžื›ืŸ, ื ื‘ื—ืŸ ืžื‘ื ื” ืžื•ืจื›ื‘ ื™ื•ืชืจ ืฉืœ ื”ื ืชื•ื ื™ื ื”ืžืชืงื‘ืœื™ื ืžืฉื™ืจื•ืช ื”ืงื™ื“ื•ื“ ื”ื’ื™ืื•ื’ืจืคื™ ืฉืœ ื’ื•ื’ืœ. ืฉืžื™ืจื” ื‘ืžื˜ืžื•ืŸ ืžื ื•ื’ื“ืช ืœื›ืœืœื™ ื”ืขื‘ื•ื“ื” ืขื ื”-API ืฉืœ ืžืคื•ืช Google, ืื– ืื ื™ ืื›ืชื•ื‘ ืชื—ื™ืœื” ืขื˜ื™ืคื” ืคืฉื•ื˜ื” ืกื‘ื™ื‘ ื”-API. ืืฉืจ ืžื‘ื•ืกืก ืขืœ ืื—ืกื•ืŸ ืžืคืชื— ื”-API ืฉืœ Google Maps ื‘ืžืฉืชื ื” ืกื‘ื™ื‘ื”; ืื ืื™ืŸ ืœืš ืืช ื”ืžืคืชื— ืœืขื‘ื•ื“ื” ืขื Google Maps API ื”ืžืื•ื—ืกืŸ ื‘ืžืฉืชื ื™ ื”ืกื‘ื™ื‘ื” ืฉืœืš, ืงื˜ืขื™ ื”ืงื•ื“ ื”ืžื•ืฆื’ื™ื ื‘ืกืขื™ืฃ ื–ื” ืœื ื™ื‘ื•ืฆืขื•.

has_key <- !identical(Sys.getenv("GOOGLE_MAPS_API_KEY"), "")
if (!has_key) {
  message("No Google Maps API key found; code chunks will not be run")
}

# https://developers.google.com/maps/documentation/geocoding
geocode <- function(address, api_key = Sys.getenv("GOOGLE_MAPS_API_KEY")) {
  url <- "https://maps.googleapis.com/maps/api/geocode/json"
  url <- paste0(url, "?address=", URLencode(address), "&key=", api_key)

  jsonlite::read_json(url)
}

ื”ืจืฉื™ืžื” ืฉื”ืคื•ื ืงืฆื™ื” ื”ื–ื• ืžื—ื–ื™ืจื” ื”ื™ื ื“ื™ ืžื•ืจื›ื‘ืช:

houston <- geocode("Houston TX")
str(houston)
#> List of 2
#>  $ results:List of 1
#>   ..$ :List of 5
#>   .. ..$ address_components:List of 4
#>   .. .. ..$ :List of 3
#>   .. .. .. ..$ long_name : chr "Houston"
#>   .. .. .. ..$ short_name: chr "Houston"
#>   .. .. .. ..$ types     :List of 2
#>   .. .. .. .. ..$ : chr "locality"
#>   .. .. .. .. ..$ : chr "political"
#>   .. .. ..$ :List of 3
#>   .. .. .. ..$ long_name : chr "Harris County"
#>   .. .. .. ..$ short_name: chr "Harris County"
#>   .. .. .. ..$ types     :List of 2
#>   .. .. .. .. ..$ : chr "administrative_area_level_2"
#>   .. .. .. .. ..$ : chr "political"
#>   .. .. ..$ :List of 3
#>   .. .. .. ..$ long_name : chr "Texas"
#>   .. .. .. ..$ short_name: chr "TX"
#>   .. .. .. ..$ types     :List of 2
#>   .. .. .. .. ..$ : chr "administrative_area_level_1"
#>   .. .. .. .. ..$ : chr "political"
#>   .. .. ..$ :List of 3
#>   .. .. .. ..$ long_name : chr "United States"
#>   .. .. .. ..$ short_name: chr "US"
#>   .. .. .. ..$ types     :List of 2
#>   .. .. .. .. ..$ : chr "country"
#>   .. .. .. .. ..$ : chr "political"
#>   .. ..$ formatted_address : chr "Houston, TX, USA"
#>   .. ..$ geometry          :List of 4
#>   .. .. ..$ bounds       :List of 2
#>   .. .. .. ..$ northeast:List of 2
#>   .. .. .. .. ..$ lat: num 30.1
#>   .. .. .. .. ..$ lng: num -95
#>   .. .. .. ..$ southwest:List of 2
#>   .. .. .. .. ..$ lat: num 29.5
#>   .. .. .. .. ..$ lng: num -95.8
#>   .. .. ..$ location     :List of 2
#>   .. .. .. ..$ lat: num 29.8
#>   .. .. .. ..$ lng: num -95.4
#>   .. .. ..$ location_type: chr "APPROXIMATE"
#>   .. .. ..$ viewport     :List of 2
#>   .. .. .. ..$ northeast:List of 2
#>   .. .. .. .. ..$ lat: num 30.1
#>   .. .. .. .. ..$ lng: num -95
#>   .. .. .. ..$ southwest:List of 2
#>   .. .. .. .. ..$ lat: num 29.5
#>   .. .. .. .. ..$ lng: num -95.8
#>   .. ..$ place_id          : chr "ChIJAYWNSLS4QIYROwVl894CDco"
#>   .. ..$ types             :List of 2
#>   .. .. ..$ : chr "locality"
#>   .. .. ..$ : chr "political"
#>  $ status : chr "OK"

ืœืžืจื‘ื” ื”ืžื–ืœ, ืื ื• ื™ื›ื•ืœื™ื ืœืคืชื•ืจ ืืช ื”ื‘ืขื™ื” ืฉืœ ื”ืžืจืช ื ืชื•ื ื™ื ืืœื” ืœื˜ื•ืคืก ื˜ื‘ืœื” ืฆืขื“ ืื—ืจ ืฆืขื“ ื‘ืืžืฆืขื•ืช ืคื•ื ืงืฆื™ื•ืช tidyr. ื›ื“ื™ ืœื”ืคื•ืš ืืช ื”ืžืฉื™ืžื” ืœืงืฆืช ื™ื•ืชืจ ืžืืชื’ืจืช ื•ืžืฆื™ืื•ืชื™ืช, ืืชื—ื™ืœ ื‘ืงื™ื“ื•ื“ ื’ื™ืื•ื’ืจืคื™ ืฉืœ ื›ืžื” ืขืจื™ื:

  city <-   c ( "Houston" , "LA" , "New York" , "Chicago" , "Springfield" )  city_geo <-   purrr::map (city, geocode) 

ืื ื™ ืืžื™ืจ ืืช ื”ืชื•ืฆืื” ื”ืžืชืงื‘ืœืช ืœ tibble, ืžื˜ืขืžื™ ื ื•ื—ื•ืช, ืื•ืกื™ืฃ ืขืžื•ื“ื” ืขื ืฉื ื”ืขื™ืจ ื”ืžืชืื™ื.

loc <- tibble(city = city, json = city_geo)
loc
#> # A tibble: 5 x 2
#>   city        json            
#>   <chr>       <list>          
#> 1 Houston     <named list [2]>
#> 2 LA          <named list [2]>
#> 3 New York    <named list [2]>
#> 4 Chicago     <named list [2]>
#> 5 Springfield <named list [2]>

ื”ืจืžื” ื”ืจืืฉื•ื ื” ืžื›ื™ืœื” ืจื›ื™ื‘ื™ื status ะธ result, ืฉืื™ืชื• ื ื•ื›ืœ ืœื”ืจื—ื™ื‘ unnest_wider() :

loc %>%
  unnest_wider(json)
#> # A tibble: 5 x 3
#>   city        results    status
#>   <chr>       <list>     <chr> 
#> 1 Houston     <list [1]> OK    
#> 2 LA          <list [1]> OK    
#> 3 New York    <list [1]> OK    
#> 4 Chicago     <list [1]> OK    
#> 5 Springfield <list [1]> OK

ืฉื™ื ืœื‘ ืฉ results ื”ื™ื ืจืฉื™ืžื” ืžืจื•ื‘ืช ืจืžื•ืช. ืœืจื•ื‘ ื”ืขืจื™ื ื™ืฉ ืืœืžื ื˜ ืื—ื“ (ื”ืžื™ื™ืฆื’ ืขืจืš ื™ื™ื—ื•ื“ื™ ื”ืžืชืื™ื ืœ-API ืฉืœ ืงื™ื“ื•ื“ ื’ื™ืื•ื’ืจืคื™), ืื‘ืœ ืœืกืคืจื™ื ื’ืคื™ืœื“ ื™ืฉ ืฉื ื™ื™ื. ืื ื—ื ื• ื™ื›ื•ืœื™ื ืœืžืฉื•ืš ืื•ืชื ืœืฉื•ืจื•ืช ื ืคืจื“ื•ืช ืขื unnest_longer() :

loc %>%
  unnest_wider(json) %>% 
  unnest_longer(results)
#> # A tibble: 5 x 3
#>   city        results          status
#>   <chr>       <list>           <chr> 
#> 1 Houston     <named list [5]> OK    
#> 2 LA          <named list [5]> OK    
#> 3 New York    <named list [5]> OK    
#> 4 Chicago     <named list [5]> OK    
#> 5 Springfield <named list [5]> OK

ื›ืขืช ืœื›ื•ืœื ื™ืฉ ืืช ืื•ืชื ืจื›ื™ื‘ื™ื, ืื•ืชื ื ื™ืชืŸ ืœืืžืช ื‘ืืžืฆืขื•ืช unnest_wider():

loc %>%
  unnest_wider(json) %>% 
  unnest_longer(results) %>% 
  unnest_wider(results)
#> # A tibble: 5 x 7
#>   city   address_componenโ€ฆ formatted_addreโ€ฆ geometry place_id  types status
#>   <chr>  <list>            <chr>            <list>   <chr>     <lis> <chr> 
#> 1 Houstโ€ฆ <list [4]>        Houston, TX, USA <named โ€ฆ ChIJAYWNโ€ฆ <lisโ€ฆ OK    
#> 2 LA     <list [4]>        Los Angeles, CAโ€ฆ <named โ€ฆ ChIJE9onโ€ฆ <lisโ€ฆ OK    
#> 3 New Yโ€ฆ <list [3]>        New York, NY, Uโ€ฆ <named โ€ฆ ChIJOwg_โ€ฆ <lisโ€ฆ OK    
#> 4 Chicaโ€ฆ <list [4]>        Chicago, IL, USA <named โ€ฆ ChIJ7cv0โ€ฆ <lisโ€ฆ OK    
#> 5 Sprinโ€ฆ <list [5]>        Springfield, MOโ€ฆ <named โ€ฆ ChIJP5jIโ€ฆ <lisโ€ฆ OK

ื ื•ื›ืœ ืœืžืฆื•ื ืืช ืงื•ืื•ืจื“ื™ื ื˜ื•ืช ืงื•ื•ื™ ื”ืจื•ื—ื‘ ื•ื”ืื•ืจืš ืฉืœ ื›ืœ ืขื™ืจ ืขืœ ื™ื“ื™ ื”ืจื—ื‘ืช ื”ืจืฉื™ืžื” geometry:

loc %>%
  unnest_wider(json) %>% 
  unnest_longer(results) %>% 
  unnest_wider(results) %>% 
  unnest_wider(geometry)
#> # A tibble: 5 x 10
#>   city  address_componeโ€ฆ formatted_addreโ€ฆ bounds location location_type
#>   <chr> <list>           <chr>            <list> <list>   <chr>        
#> 1 Housโ€ฆ <list [4]>       Houston, TX, USA <nameโ€ฆ <named โ€ฆ APPROXIMATE  
#> 2 LA    <list [4]>       Los Angeles, CAโ€ฆ <nameโ€ฆ <named โ€ฆ APPROXIMATE  
#> 3 New โ€ฆ <list [3]>       New York, NY, Uโ€ฆ <nameโ€ฆ <named โ€ฆ APPROXIMATE  
#> 4 Chicโ€ฆ <list [4]>       Chicago, IL, USA <nameโ€ฆ <named โ€ฆ APPROXIMATE  
#> 5 Spriโ€ฆ <list [5]>       Springfield, MOโ€ฆ <nameโ€ฆ <named โ€ฆ APPROXIMATE  
#> # โ€ฆ with 4 more variables: viewport <list>, place_id <chr>, types <list>,
#> #   status <chr>

ื•ืื– ื”ืžื™ืงื•ื ืฉืขื‘ื•ืจื• ืืชื” ืฆืจื™ืš ืœื”ืจื—ื™ื‘ location:

loc %>%
  unnest_wider(json) %>%
  unnest_longer(results) %>%
  unnest_wider(results) %>%
  unnest_wider(geometry) %>%
  unnest_wider(location)
#> # A tibble: 5 x 11
#>   city  address_componeโ€ฆ formatted_addreโ€ฆ bounds   lat    lng location_type
#>   <chr> <list>           <chr>            <list> <dbl>  <dbl> <chr>        
#> 1 Housโ€ฆ <list [4]>       Houston, TX, USA <nameโ€ฆ  29.8  -95.4 APPROXIMATE  
#> 2 LA    <list [4]>       Los Angeles, CAโ€ฆ <nameโ€ฆ  34.1 -118.  APPROXIMATE  
#> 3 New โ€ฆ <list [3]>       New York, NY, Uโ€ฆ <nameโ€ฆ  40.7  -74.0 APPROXIMATE  
#> 4 Chicโ€ฆ <list [4]>       Chicago, IL, USA <nameโ€ฆ  41.9  -87.6 APPROXIMATE  
#> 5 Spriโ€ฆ <list [5]>       Springfield, MOโ€ฆ <nameโ€ฆ  37.2  -93.3 APPROXIMATE  
#> # โ€ฆ with 4 more variables: viewport <list>, place_id <chr>, types <list>,
#> #   status <chr>

ื•ื‘ื›ืœ ื–ืืช ืฉื•ื‘ ืคืขื, unnest_auto() ืžืคืฉื˜ ืืช ื”ืคืขื•ืœื” ื”ืžืชื•ืืจืช ืขื ื›ืžื” ืกื™ื›ื•ื ื™ื ืฉืขืœื•ืœื™ื ืœื”ื™ื’ืจื ืžืฉื™ื ื•ื™ ืžื‘ื ื” ื”ื ืชื•ื ื™ื ื”ื ื›ื ืกื™ื:

loc %>%
  unnest_auto(json) %>%
  unnest_auto(results) %>%
  unnest_auto(results) %>%
  unnest_auto(geometry) %>%
  unnest_auto(location)
#> Using `unnest_wider(json)`; elements have 2 names in common
#> Using `unnest_longer(results)`; no element has names
#> Using `unnest_wider(results)`; elements have 5 names in common
#> Using `unnest_wider(geometry)`; elements have 4 names in common
#> Using `unnest_wider(location)`; elements have 2 names in common
#> # A tibble: 5 x 11
#>   city  address_componeโ€ฆ formatted_addreโ€ฆ bounds   lat    lng location_type
#>   <chr> <list>           <chr>            <list> <dbl>  <dbl> <chr>        
#> 1 Housโ€ฆ <list [4]>       Houston, TX, USA <nameโ€ฆ  29.8  -95.4 APPROXIMATE  
#> 2 LA    <list [4]>       Los Angeles, CAโ€ฆ <nameโ€ฆ  34.1 -118.  APPROXIMATE  
#> 3 New โ€ฆ <list [3]>       New York, NY, Uโ€ฆ <nameโ€ฆ  40.7  -74.0 APPROXIMATE  
#> 4 Chicโ€ฆ <list [4]>       Chicago, IL, USA <nameโ€ฆ  41.9  -87.6 APPROXIMATE  
#> 5 Spriโ€ฆ <list [5]>       Springfield, MOโ€ฆ <nameโ€ฆ  37.2  -93.3 APPROXIMATE  
#> # โ€ฆ with 4 more variables: viewport <list>, place_id <chr>, types <list>,
#> #   status <chr>

ืื ื—ื ื• ื™ื›ื•ืœื™ื ื’ื ืคืฉื•ื˜ ืœื”ืกืชื›ืœ ืขืœ ื”ื›ืชื•ื‘ืช ื”ืจืืฉื•ื ื” ืฉืœ ื›ืœ ืขื™ืจ:

loc %>%
  unnest_wider(json) %>%
  hoist(results, first_result = 1) %>%
  unnest_wider(first_result) %>%
  unnest_wider(geometry) %>%
  unnest_wider(location)
#> # A tibble: 5 x 11
#>   city  address_componeโ€ฆ formatted_addreโ€ฆ bounds   lat    lng location_type
#>   <chr> <list>           <chr>            <list> <dbl>  <dbl> <chr>        
#> 1 Housโ€ฆ <list [4]>       Houston, TX, USA <nameโ€ฆ  29.8  -95.4 APPROXIMATE  
#> 2 LA    <list [4]>       Los Angeles, CAโ€ฆ <nameโ€ฆ  34.1 -118.  APPROXIMATE  
#> 3 New โ€ฆ <list [3]>       New York, NY, Uโ€ฆ <nameโ€ฆ  40.7  -74.0 APPROXIMATE  
#> 4 Chicโ€ฆ <list [4]>       Chicago, IL, USA <nameโ€ฆ  41.9  -87.6 APPROXIMATE  
#> 5 Spriโ€ฆ <list [5]>       Springfield, MOโ€ฆ <nameโ€ฆ  37.2  -93.3 APPROXIMATE  
#> # โ€ฆ with 4 more variables: viewport <list>, place_id <chr>, types <list>,
#> #   status <chr>

ืื• ืœื”ืฉืชืžืฉ hoist() ืœืฆืœื™ืœื” ืžืจื•ื‘ืช ืจืžื•ืช ืœืœื›ืช ื™ืฉื™ืจื•ืช ืืœื™ื” lat ะธ lng.

loc %>%
  hoist(json,
    lat = list("results", 1, "geometry", "location", "lat"),
    lng = list("results", 1, "geometry", "location", "lng")
  )
#> # A tibble: 5 x 4
#>   city          lat    lng json            
#>   <chr>       <dbl>  <dbl> <list>          
#> 1 Houston      29.8  -95.4 <named list [2]>
#> 2 LA           34.1 -118.  <named list [2]>
#> 3 New York     40.7  -74.0 <named list [2]>
#> 4 Chicago      41.9  -87.6 <named list [2]>
#> 5 Springfield  37.2  -93.3 <named list [2]>

ื“ื™ืกืงื•ื’ืจืคื™ื” ืฉืœ ืฉืจืœื” ื’ืœืคื ื“

ืœื‘ืกื•ืฃ, ื ื‘ื—ืŸ ืืช ื”ืžื‘ื ื” ื”ืžื•ืจื›ื‘ ื‘ื™ื•ืชืจ - ื”ื“ื™ืกืงื•ื’ืจืคื™ื” ืฉืœ ืฉืจืœื” ื’ืœืคื ื“. ื›ืžื• ื‘ื“ื•ื’ืžืื•ืช ืœืžืขืœื”, ืื ื• ืžืชื—ื™ืœื™ื ื‘ื”ืžืจืช ื”ืจืฉื™ืžื” ืœืžืกื’ืจืช ื ืชื•ื ื™ื ืฉืœ ืขืžื•ื“ื” ืื—ืช, ื•ืœืื—ืจ ืžื›ืŸ ืžืจื—ื™ื‘ื™ื ืื•ืชื” ื›ืš ืฉื›ืœ ืจื›ื™ื‘ ื™ื”ื™ื” ืขืžื•ื“ื” ื ืคืจื“ืช. ื’ื ืื ื™ ืžืฉื ื” ืืช ื”ืขืžื•ื“ื” date_added ืœืคื•ืจืžื˜ ื”ืชืืจื™ืš ื•ื”ืฉืขื” ื”ืžืชืื™ื ื‘-R.

discs <- tibble(disc = discog) %>% 
  unnest_wider(disc) %>% 
  mutate(date_added = as.POSIXct(strptime(date_added, "%Y-%m-%dT%H:%M:%S"))) 
discs
#> # A tibble: 155 x 5
#>    instance_id date_added          basic_information       id rating
#>          <int> <dttm>              <list>               <int>  <int>
#>  1   354823933 2019-02-16 17:48:59 <named list [11]>  7496378      0
#>  2   354092601 2019-02-13 14:13:11 <named list [11]>  4490852      0
#>  3   354091476 2019-02-13 14:07:23 <named list [11]>  9827276      0
#>  4   351244906 2019-02-02 11:39:58 <named list [11]>  9769203      0
#>  5   351244801 2019-02-02 11:39:37 <named list [11]>  7237138      0
#>  6   351052065 2019-02-01 20:40:53 <named list [11]> 13117042      0
#>  7   350315345 2019-01-29 15:48:37 <named list [11]>  7113575      0
#>  8   350315103 2019-01-29 15:47:22 <named list [11]> 10540713      0
#>  9   350314507 2019-01-29 15:44:08 <named list [11]> 11260950      0
#> 10   350314047 2019-01-29 15:41:35 <named list [11]> 11726853      0
#> # โ€ฆ with 145 more rows

ื‘ืจืžื” ื–ื•, ืื ื• ืžืงื‘ืœื™ื ืžื™ื“ืข ืขืœ ืžืชื™ ื›ืœ ื“ื™ืกืง ื”ืชื•ื•ืกืฃ ืœื“ื™ืกืงื•ื’ืจืคื™ื” ืฉืœ ืฉืจืœื”, ืืš ืื™ื ื ื• ืจื•ืื™ื ื ืชื•ื ื™ื ืขืœ ื”ื“ื™ืกืงื™ื ื”ืœืœื•. ืœืฉื ื›ืš ืขืœื™ื ื• ืœื”ืจื—ื™ื‘ ืืช ื”ืขืžื•ื“ื” basic_information:

discs %>% unnest_wider(basic_information)
#> Column name `id` must not be duplicated.
#> Use .name_repair to specify repair.

ืœืฆืขืจื ื•, ื ืงื‘ืœ ืฉื’ื™ืื”, ื›ื™... ื‘ืชื•ืš ื”ืจืฉื™ืžื” basic_information ื™ืฉ ืขืžื•ื“ื” ื‘ืื•ืชื• ืฉื basic_information. ืื ืžืชืจื—ืฉืช ืฉื’ื™ืื” ื›ื–ื•, ื›ื“ื™ ืœืงื‘ื•ืข ื‘ืžื”ื™ืจื•ืช ืืช ื”ืกื™ื‘ื” ืœื”, ืืชื” ื™ื›ื•ืœ ืœื”ืฉืชืžืฉ names_repair = "unique":

discs %>% unnest_wider(basic_information, names_repair = "unique")
#> New names:
#> * id -> id...6
#> * id -> id...14
#> # A tibble: 155 x 15
#>    instance_id date_added          labels  year artists id...6 thumb title
#>          <int> <dttm>              <list> <int> <list>   <int> <chr> <chr>
#>  1   354823933 2019-02-16 17:48:59 <listโ€ฆ  2015 <list โ€ฆ 7.50e6 httpโ€ฆ Demo 
#>  2   354092601 2019-02-13 14:13:11 <listโ€ฆ  2013 <list โ€ฆ 4.49e6 httpโ€ฆ Obseโ€ฆ
#>  3   354091476 2019-02-13 14:07:23 <listโ€ฆ  2017 <list โ€ฆ 9.83e6 httpโ€ฆ I    
#>  4   351244906 2019-02-02 11:39:58 <listโ€ฆ  2017 <list โ€ฆ 9.77e6 httpโ€ฆ Oรญdoโ€ฆ
#>  5   351244801 2019-02-02 11:39:37 <listโ€ฆ  2015 <list โ€ฆ 7.24e6 httpโ€ฆ A Caโ€ฆ
#>  6   351052065 2019-02-01 20:40:53 <listโ€ฆ  2019 <list โ€ฆ 1.31e7 httpโ€ฆ Tashโ€ฆ
#>  7   350315345 2019-01-29 15:48:37 <listโ€ฆ  2014 <list โ€ฆ 7.11e6 httpโ€ฆ Demo 
#>  8   350315103 2019-01-29 15:47:22 <listโ€ฆ  2015 <list โ€ฆ 1.05e7 httpโ€ฆ Let โ€ฆ
#>  9   350314507 2019-01-29 15:44:08 <listโ€ฆ  2017 <list โ€ฆ 1.13e7 ""    Sub โ€ฆ
#> 10   350314047 2019-01-29 15:41:35 <listโ€ฆ  2017 <list โ€ฆ 1.17e7 httpโ€ฆ Demo 
#> # โ€ฆ with 145 more rows, and 7 more variables: formats <list>,
#> #   cover_image <chr>, resource_url <chr>, master_id <int>,
#> #   master_url <chr>, id...14 <int>, rating <int>

ื”ื‘ืขื™ื” ื”ื™ื basic_information ื—ื•ื–ืจ ืขืœ ืขืžื•ื“ืช ื”ืžื–ื”ื” ื”ืžืื•ื—ืกื ืช ื’ื ื‘ืจืžื” ื”ืขืœื™ื•ื ื”, ื›ืš ืฉื ื•ื›ืœ ืคืฉื•ื˜ ืœื”ืกื™ืจ ืื•ืชื”:

discs %>% 
  select(-id) %>% 
  unnest_wider(basic_information)
#> # A tibble: 155 x 14
#>    instance_id date_added          labels  year artists     id thumb title
#>          <int> <dttm>              <list> <int> <list>   <int> <chr> <chr>
#>  1   354823933 2019-02-16 17:48:59 <listโ€ฆ  2015 <list โ€ฆ 7.50e6 httpโ€ฆ Demo 
#>  2   354092601 2019-02-13 14:13:11 <listโ€ฆ  2013 <list โ€ฆ 4.49e6 httpโ€ฆ Obseโ€ฆ
#>  3   354091476 2019-02-13 14:07:23 <listโ€ฆ  2017 <list โ€ฆ 9.83e6 httpโ€ฆ I    
#>  4   351244906 2019-02-02 11:39:58 <listโ€ฆ  2017 <list โ€ฆ 9.77e6 httpโ€ฆ Oรญdoโ€ฆ
#>  5   351244801 2019-02-02 11:39:37 <listโ€ฆ  2015 <list โ€ฆ 7.24e6 httpโ€ฆ A Caโ€ฆ
#>  6   351052065 2019-02-01 20:40:53 <listโ€ฆ  2019 <list โ€ฆ 1.31e7 httpโ€ฆ Tashโ€ฆ
#>  7   350315345 2019-01-29 15:48:37 <listโ€ฆ  2014 <list โ€ฆ 7.11e6 httpโ€ฆ Demo 
#>  8   350315103 2019-01-29 15:47:22 <listโ€ฆ  2015 <list โ€ฆ 1.05e7 httpโ€ฆ Let โ€ฆ
#>  9   350314507 2019-01-29 15:44:08 <listโ€ฆ  2017 <list โ€ฆ 1.13e7 ""    Sub โ€ฆ
#> 10   350314047 2019-01-29 15:41:35 <listโ€ฆ  2017 <list โ€ฆ 1.17e7 httpโ€ฆ Demo 
#> # โ€ฆ with 145 more rows, and 6 more variables: formats <list>,
#> #   cover_image <chr>, resource_url <chr>, master_id <int>,
#> #   master_url <chr>, rating <int>

ืœื—ืœื•ืคื™ืŸ, ื ื•ื›ืœ ืœื”ืฉืชืžืฉ hoist():

discs %>% 
  hoist(basic_information,
    title = "title",
    year = "year",
    label = list("labels", 1, "name"),
    artist = list("artists", 1, "name")
  )
#> # A tibble: 155 x 9
#>    instance_id date_added          title  year label artist
#>          <int> <dttm>              <chr> <int> <chr> <chr> 
#>  1   354823933 2019-02-16 17:48:59 Demo   2015 Tobiโ€ฆ Mollot
#>  2   354092601 2019-02-13 14:13:11 Obseโ€ฆ  2013 La Vโ€ฆ Una Bโ€ฆ
#>  3   354091476 2019-02-13 14:07:23 I      2017 La Vโ€ฆ S.H.Iโ€ฆ
#>  4   351244906 2019-02-02 11:39:58 Oรญdoโ€ฆ  2017 La Vโ€ฆ Rata โ€ฆ
#>  5   351244801 2019-02-02 11:39:37 A Caโ€ฆ  2015 Katoโ€ฆ Ivy (โ€ฆ
#>  6   351052065 2019-02-01 20:40:53 Tashโ€ฆ  2019 Highโ€ฆ Tashme
#>  7   350315345 2019-01-29 15:48:37 Demo   2014 Mindโ€ฆ Desgrโ€ฆ
#>  8   350315103 2019-01-29 15:47:22 Let โ€ฆ  2015 Not โ€ฆ Phantโ€ฆ
#>  9   350314507 2019-01-29 15:44:08 Sub โ€ฆ  2017 Not โ€ฆ Sub Sโ€ฆ
#> 10   350314047 2019-01-29 15:41:35 Demo   2017 Presโ€ฆ Smallโ€ฆ
#> # โ€ฆ with 145 more rows, and 3 more variables: basic_information <list>,
#> #   id <int>, rating <int>

ื›ืืŸ ืื ื™ ืื—ื–ืจ ื‘ืžื”ื™ืจื•ืช ืืช ื”ืชื•ื•ื™ืช ื•ืืช ืฉื ื”ืืžืŸ ื”ืจืืฉื•ืŸ ืœืคื™ ืื™ื ื“ืงืก ืขืœ ื™ื“ื™ ืฆืœื™ืœื” ืœืชื•ืš ื”ืจืฉื™ืžื” ื”ืžืงื•ื ื ืช.

ื’ื™ืฉื” ืฉื™ื˜ืชื™ืช ื™ื•ืชืจ ื”ื™ื ืœื™ืฆื•ืจ ื˜ื‘ืœืื•ืช ื ืคืจื“ื•ืช ืœืืžืŸ ื•ืœืชื•ื•ื™ืช:

discs %>% 
  hoist(basic_information, artist = "artists") %>% 
  select(disc_id = id, artist) %>% 
  unnest_longer(artist) %>% 
  unnest_wider(artist)
#> # A tibble: 167 x 8
#>     disc_id join  name        anv   tracks role  resource_url            id
#>       <int> <chr> <chr>       <chr> <chr>  <chr> <chr>                <int>
#>  1  7496378 ""    Mollot      ""    ""     ""    https://api.discogโ€ฆ 4.62e6
#>  2  4490852 ""    Una Bรจstiaโ€ฆ ""    ""     ""    https://api.discogโ€ฆ 3.19e6
#>  3  9827276 ""    S.H.I.T. (โ€ฆ ""    ""     ""    https://api.discogโ€ฆ 2.77e6
#>  4  9769203 ""    Rata Negra  ""    ""     ""    https://api.discogโ€ฆ 4.28e6
#>  5  7237138 ""    Ivy (18)    ""    ""     ""    https://api.discogโ€ฆ 3.60e6
#>  6 13117042 ""    Tashme      ""    ""     ""    https://api.discogโ€ฆ 5.21e6
#>  7  7113575 ""    Desgraciadโ€ฆ ""    ""     ""    https://api.discogโ€ฆ 4.45e6
#>  8 10540713 ""    Phantom Heโ€ฆ ""    ""     ""    https://api.discogโ€ฆ 4.27e6
#>  9 11260950 ""    Sub Space โ€ฆ ""    ""     ""    https://api.discogโ€ฆ 5.69e6
#> 10 11726853 ""    Small Man โ€ฆ ""    ""     ""    https://api.discogโ€ฆ 6.37e6
#> # โ€ฆ with 157 more rows

discs %>% 
  hoist(basic_information, format = "formats") %>% 
  select(disc_id = id, format) %>% 
  unnest_longer(format) %>% 
  unnest_wider(format) %>% 
  unnest_longer(descriptions)
#> # A tibble: 280 x 5
#>     disc_id descriptions text  name     qty  
#>       <int> <chr>        <chr> <chr>    <chr>
#>  1  7496378 Numbered     Black Cassette 1    
#>  2  4490852 LP           <NA>  Vinyl    1    
#>  3  9827276 "7""        <NA>  Vinyl    1    
#>  4  9827276 45 RPM       <NA>  Vinyl    1    
#>  5  9827276 EP           <NA>  Vinyl    1    
#>  6  9769203 LP           <NA>  Vinyl    1    
#>  7  9769203 Album        <NA>  Vinyl    1    
#>  8  7237138 "7""        <NA>  Vinyl    1    
#>  9  7237138 45 RPM       <NA>  Vinyl    1    
#> 10 13117042 "7""        <NA>  Vinyl    1    
#> # โ€ฆ with 270 more rows

ืœืื—ืจ ืžื›ืŸ ืชื•ื›ืœ ืœื”ืฆื˜ืจืฃ ืืœื™ื”ื ื‘ื—ื–ืจื” ืœืžืขืจืš ื”ื ืชื•ื ื™ื ื”ืžืงื•ืจื™ ืœืคื™ ื”ืฆื•ืจืš.

ืžืกืงื ื”

ืขื“ ืœื™ื‘ื” ืฉืœ ื”ืกืคืจื™ื™ื” tidyverse ื›ื•ืœืœ ื—ื‘ื™ืœื•ืช ืฉื™ืžื•ืฉื™ื•ืช ืจื‘ื•ืช ื”ืžืื•ื—ื“ื•ืช ืขืœ ื™ื“ื™ ืคื™ืœื•ืกื•ืคื™ื™ืช ืขื™ื‘ื•ื“ ื ืชื•ื ื™ื ืžืฉื•ืชืคืช.

ื‘ืžืืžืจ ื–ื” ื‘ื—ื ื• ืืช ืžืฉืคื—ืช ื”ืชืคืงื•ื“ื™ื unnest_*(), ืฉืžื˜ืจืชื ืœืขื‘ื•ื“ ืขื ื—ื™ืœื•ืฅ ืืœืžื ื˜ื™ื ืžืจืฉื™ืžื•ืช ืžืงื•ื ื ื•ืช. ื—ื‘ื™ืœื” ื–ื• ืžื›ื™ืœื” ืชื›ื•ื ื•ืช ืฉื™ืžื•ืฉื™ื•ืช ืจื‘ื•ืช ืื—ืจื•ืช ื”ืžืงืœื•ืช ืขืœ ื”ืžืจืช ื ืชื•ื ื™ื ื‘ื”ืชืื ืœืงื•ื ืกืคื˜ ื ืชื•ื ื™ื ืžืกื•ื“ืจื™ื.

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”