[英]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 summarise
在
summarise
的list
中返回 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.1
, wt.2
等列是矩阵的一部分,要获得 output 作为单独的列,您可以这样做
data.frame(cyl = tmp$cyl, tmp$wt)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.