简体   繁体   English

如何从 R 中的向量创建单行数据框?

[英]How to create a one-row data frame from a vector in R?

What is the most concise and/or elegant way to turn a vector into a single-row data frame in R?在 R 中将向量转换为单行数据框的最简洁和/或优雅的方法是什么? I'm trying to use a function that returns a 5-element vector and apply it across groups in my data frame, like so:我正在尝试使用 function 返回一个 5 元素向量并将其应用于我的数据框中的组,如下所示:

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

I'd like to have these results as rows in a new data frame, rather than a list of vectors, so I can plot with them in ggplot.我想将这些结果作为新数据框中的行,而不是向量列表,所以我可以在 ggplot 中使用 plot 。 But the best I've come up with is to add do.call(rbind, .) %>% as.data.frame to the end of my pipeline, which seems ungainly and inelegant.但是我想出的最好的方法是将do.call(rbind, .) %>% as.data.frame添加到我的管道末尾,这看起来既笨拙又不优雅。 Replacing the group_map with a group_modify seems like the answer, but the function complains that my results aren't a data frame.group_map替换group_modify似乎是答案,但 function 抱怨我的结果不是数据框。 And wrapping the anonymous function in a call to tibble_row doesn't work because tibble_row won't take vectors, just individual elements or explicit list columns.并且在对 tibble_row 的调用中包装匿名tibble_row不起作用,因为tibble_row不会采用向量,而只是单个元素或显式列表列。

Ideally, output would look like:理想情况下,output 看起来像:

  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

Surely there's a more elegant way to do what I'm trying to do, ideally within the tidyverse framework?当然有一种更优雅的方式来做我想做的事情,最好是在 tidyverse 框架内?

We could use unnest_wider after returning the output in a list in summarisesummariselist中返回 output 后,我们可以使用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

Or if we want to use the OP's method, then set the names for that vector and use as_tibble_row或者,如果我们想使用 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

As the output of group_map is always a list , it may be better to use group_modify to return a tbl thus avoiding the last map_dfr/bind_rows由于 group_map 的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

Base R method with aggregate :使用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

The wt.1 , wt.2 etc columns are part of matrix, to get the output as individual columns you can do wt.1wt.2等列是矩阵的一部分,要获得 output 作为单独的列,您可以这样做

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM