tidyverse - 将命名向量转换为data.frame / tibble的首选方法

时间:2016-10-14 06:17:37

标签: r dplyr tidyr purrr tidyverse

经常使用tidyverse我经常面临将命名向量转换为data.frame / tibble并将列作为向量名称的挑战。
这样做的首选方式是什么?
编辑:这与:thisthis github-issue

有关

所以我想:

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

成为这个:

# A tibble: 1 × 2
      a     b
  <dbl> <dbl>
1     1     2

我可以通过例如:

来做到这一点
vec %>% enframe %>% spread(name, value)
vec %>% t %>% as_tibble

用例示例:

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)

哪个给出了

# A tibble: 2 × 3
      a     b     c
  <chr> <chr> <chr>
1     1     2  <NA>
2     1  <NA>     3

4 个答案:

答案 0 :(得分:14)

现在使用bind_rows(在dplyr 0.7.0中引入)直接支持此功能:

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

bind_rows(vec)
#> # A tibble: 1 x 2
#>       a     b
#>   <dbl> <dbl>
#> 1     1     2

https://cran.r-project.org/web/packages/dplyr/news.html的引用解释了这一变化:

  

bind_rows()bind_cols()现在接受矢量。前者将它们视为行,后者将列视为列。行需要内部名称,如c(col1 = 1, col2 = 2),而列需要外部名称:col1 = c(1, 2)。列表仍被视为数据框,但可以使用!!!明确拼接,例如bind_rows(!!! x)(#1676)。

通过此更改,意味着用例示例中的以下行:

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

可以改写为

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

也等同于

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

以下示例演示了不同方法的等效性:

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
#>       a     b     c
#>   <chr> <chr> <chr>
#> 1     1     2  <NA>
#> 2     1  <NA>     3

答案 1 :(得分:2)

惯用的方法是在!!!调用中用tibble()拼接向量,使命名的向量元素成为列定义:

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

reprex package(v0.3.0)于2019-09-14创建

答案 2 :(得分:1)

有趣的是,您可以使用列表的as_tibble()方法在一次调用中执行此操作。请注意,这不是最佳做法,因为这不是导出的方法。

tibble:::as_tibble.list(vec)

答案 3 :(得分:0)

这对我有用:c("a" = 1, "b" = 2) %>% t() %>% tbl_df()