【问题标题】:How to create a one-row data frame from a vector in R?如何从 R 中的向量创建单行数据框?
【发布时间】:2021-07-11 22:41:45
【问题描述】:

在 R 中将向量转换为单行数据框的最简洁和/或优雅的方法是什么?我正在尝试使用一个返回 5 元素向量并将其应用于我的数据框中的组的函数,如下所示:

library(tidyverse)
mtcars %>% 
  group_by(cyl) %>% 
  group_map(~boxplot.stats(.$wt)$stats)

我希望将这些结果作为新数据框中的行,而不是向量列表,因此我可以在 ggplot 中使用它们进行绘图。但是我想出的最好的方法是将do.call(rbind, .) %>% as.data.frame 添加到我的管道末尾,这看起来既笨拙又不优雅。用group_modify 替换group_map 似乎是答案,但该函数抱怨我的结果不是数据框。并且将匿名函数包装在对 tibble_row 的调用中不起作用,因为 tibble_row 不会采用向量,仅采用单个元素或显式列表列。

理想情况下,输出如下所示:

  cyl    V1     V2    V3     V4   V5
1   4 1.513 1.8850 2.200 2.6225 3.19
2   6 2.620 2.8225 3.215 3.4400 3.46
3   8 3.170 3.5200 3.755 4.0700 4.07

肯定有一种更优雅的方式来做我想做的事情,最好是在 tidyverse 框架内?

【问题讨论】:

    标签: r tidyverse


    【解决方案1】:

    带有aggregate的基本R方法:

    tmp <- aggregate(wt~cyl, mtcars, function(x) boxplot.stats(x)$stats)
    tmp
    
    #  cyl   wt.1   wt.2   wt.3   wt.4   wt.5
    #1   4 1.5130 1.8850 2.2000 2.6225 3.1900
    #2   6 2.6200 2.8225 3.2150 3.4400 3.4600
    #3   8 3.1700 3.5200 3.7550 4.0700 4.0700
    

    wt.1wt.2 等列是矩阵的一部分,您可以将输出作为单独的列进行

    data.frame(cyl = tmp$cyl, tmp$wt)
    

    【讨论】:

      【解决方案2】:

      我们可以在list in summarise 中返回输出后使用unnest_wider

      library(dplyr)
      library(tidyr)
      mtcars %>%
          group_by(cyl) %>%
          summarise(out = list(boxplot.stats(wt)$stats)) %>% 
          unnest_wider(out) %>% 
          rename_at(-1, ~ str_replace(., '\\.+', 'x'))
      # A tibble: 3 x 6
      #    cyl    x1    x2    x3    x4    x5
      #   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
      #1     4  1.51  1.88  2.2   2.62  3.19
      #2     6  2.62  2.82  3.22  3.44  3.46
      #3     8  3.17  3.52  3.76  4.07  4.07
      

      或者,如果我们想使用 OP 的方法,则为 vector 设置名称并使用 as_tibble_row

      library(purrr)
      library(stringr)
      mtcars %>% 
        group_by(cyl) %>% 
        group_map(~ tibble(cyl = first(.x$cyl), 
                setNames(boxplot.stats(.$wt)$stats, str_c('x', 1:5)) %>% 
                   as_tibble_row) , .keep = TRUE) %>%
        bind_rows
      # A tibble: 3 x 6
      #    cyl    x1    x2    x3    x4    x5
      #  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
      #1     4  1.51  1.88  2.2   2.62  3.19
      #2     6  2.62  2.82  3.22  3.44  3.46
      #3     8  3.17  3.52  3.76  4.07  4.07
      

      由于group_map 的输出始终是list,最好使用group_modify 返回tbl,从而避免最后一个map_dfr/bind_rows

      mtcars %>% 
        group_by(cyl) %>% 
        group_modify(~ setNames(boxplot.stats(.$wt)$stats, str_c('x', 1:5)) %>%
               as_tibble_row , .keep = TRUE) %>% 
        ungroup
      # A tibble: 3 x 6
      #    cyl    x1    x2    x3    x4    x5
      #  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
      #1     4  1.51  1.88  2.2   2.62  3.19
      #2     6  2.62  2.82  3.22  3.44  3.46
      #3     8  3.17  3.52  3.76  4.07  4.07
      

      【讨论】:

      • 哇!我以前从未见过 group_map 和 co...。这似乎是一个实验级别的全新功能。看起来很神奇。
      • 这两个函数我也是第一次见。否则,我总是 group_split 并在每次拆分时遵循地图。 +1
      • @AnilGoyal 很高兴在这里见到你,我正要联系你讨论这些材料。太棒了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多