Tidyverse is the preferred way to turn a named vector into data.frame / tibble

Using tidyverse , I often run into the problem of turning named vectors into data.frame / tibble , with the columns being the names of the vector.
What is the preferred / tidyversey way to do this?
EDIT: This is related to: this and this github- question

So I want:

 require(tidyverse) vec <- c("a" = 1, "b" = 2) 

to become next:

 # A tibble: 1 Γ— 2 ab <dbl> <dbl> 1 1 2 

I can do this, for example:

 vec %>% enframe %>% spread(name, value) vec %>% t %>% as_tibble 

Usecase example:

 require(tidyverse) require(rvest) txt <- c('<node a="1" b="2"></node>', '<node a="1" c="3"></node>') txt %>% map(read_xml) %>% map(xml_attrs) %>% map_df(~t(.) %>% as_tibble) 

What gives

 # A tibble: 2 Γ— 3 abc <chr> <chr> <chr> 1 1 2 <NA> 2 1 <NA> 3 
+5
source share
3 answers

Now this is supported directly with bind_rows (introduced in dplyr 0.7.0 ):

 library(tidyverse)) vec <- c("a" = 1, "b" = 2) bind_rows(vec) #> # A tibble: 1 x 2 #> ab #> <dbl> <dbl> #> 1 1 2 

This quote from https://cran.r-project.org/web/packages/dplyr/news.html explains the change:

bind_rows() and bind_cols() now accept vectors. They are considered as rows of the first and columns of the last. Rows require internal names, such as c(col1 = 1, col2 = 2) , and columns require external names: col1 = c(1, 2) . Lists are still treated as data frames, but they can be explicitly joined using !!! , eg. bind_rows(!!! x) (# 1676).

With this change, this means the following line in the usage example:

txt %>% map(read_xml) %>% map(xml_attrs) %>% map_df(~t(.) %>% as_tibble)

can be rewritten as

txt %>% map(read_xml) %>% map(xml_attrs) %>% map_df(bind_rows)

which is also equivalent

txt %>% map(read_xml) %>% map(xml_attrs) %>% { bind_rows(!!! .) }

The equivalence of the various approaches is demonstrated in the following example:

 library(tidyverse) library(rvest) txt <- c('<node a="1" b="2"></node>', '<node a="1" c="3"></node>') temp <- txt %>% map(read_xml) %>% map(xml_attrs) # x, y, and z are identical x <- temp %>% map_df(~t(.) %>% as_tibble) y <- temp %>% map_df(bind_rows) z <- bind_rows(!!! temp) identical(x, y) #> [1] TRUE identical(y, z) #> [1] TRUE z #> # A tibble: 2 x 3 #> abc #> <chr> <chr> <chr> #> 1 1 2 <NA> #> 2 1 <NA> 3 
+3
source

This works for me: c("a" = 1, "b" = 2) %>% t() %>% tbl_df()

0
source

Interestingly, you can use the as_tibble() method for lists to do this in one call. Please note that this is not the best practice as it is not an exported method.

 tibble:::as_tibble.list(vec) 
0
source

Source: https://habr.com/ru/post/1258193/


All Articles