经常使用tidyverse
我经常面临将命名向量转换为data.frame
/ tibble
并将列作为向量名称的挑战。
这样做的首选方式是什么?
编辑:这与:this和this 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
答案 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()