【问题标题】:tidyverse - prefered way to turn a named vector into a data.frame/tibbletidyverse - 将命名向量转换为 data.frame/tibble 的首选方法
【发布时间】:2017-02-23 11:24:24
【问题描述】:

经常使用tidyverse,我经常面临将命名向量转换为data.frame/tibble 的挑战,其中列是向量的名称。
什么是首选/tidyversey这样做的方式?
编辑:这与:thisthisgithub-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

【问题讨论】:

  • 你认为你正在做的事情到底有什么不足(如果有的话?)
  • 我也问过自己同样的问题,因为bind_rows 不能代替map_df(~t(.) %&gt;% as_tibble) 工作。所以,到现在为止,我转置,转换为字符串保留字符(不是因子)的数据帧,然后将结果绑定在一起。但是,这个常见任务的快捷方式可能会很好。
  • @lukeA,我认为bind_rows 已经更新,现在可以按照您想要的方式工作

标签: r dplyr tidyr purrr tidyverse


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    tibble:::as_tibble.list(vec)
    

    【讨论】:

      【解决方案3】:

      现在使用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 %&gt;% map(read_xml) %&gt;% map(xml_attrs) %&gt;% map_df(~t(.) %&gt;% as_tibble)

      可以改写为

      txt %&gt;% map(read_xml) %&gt;% map(xml_attrs) %&gt;% map_df(bind_rows)

      也等价于

      txt %&gt;% map(read_xml) %&gt;% map(xml_attrs) %&gt;% { 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
      

      【讨论】:

      【解决方案4】:

      惯用的方法是在 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 创建

      【讨论】:

        猜你喜欢
        • 2013-05-24
        • 2021-02-22
        • 1970-01-01
        • 2011-10-27
        • 2021-07-23
        • 2021-12-10
        相关资源
        最近更新 更多