这是一个代码段:
y <- purrr::map(1:2, ~ c(a=.x))
test1 <- dplyr::bind_rows(y)
test2 <- do.call(dplyr::bind_rows, y)
第一次调用bind_rows
(test1
)会产生错误
Error in bind_rows_(x, .id) : Argument 1 must have names
另一方面,使用do.call
调用bind_rows
(test2
)可以按预期工作:
test2
# A tibble: 2 x 1
a
<int>
1 1
2 2
为什么?这使用的是dplyr 0.7.6和purrr 0.2.5。如果我使用map_df
而不是map
,它将失败,并显示相同的错误。
注意:在我看来,这个问题与Error in bind_rows_(x, .id) : Argument 1 must have names using map_df in purrr相同。
编辑:解决此问题的另一种方法是首先显式创建一个数据框:
y <- purrr::map(1:2, ~ data.frame(a=.x))
test1
和test2
现在创建时没有错误,并且完全相同。
或者,这一步创建了test2
数据帧:
purrr::map_df(1:2, ~ data.frame(a=.x))
答案 0 :(得分:3)
摘自bind_rows
的文档:
请注意,由于历史原因,列表包含向量总是 视为数据帧。因此,它们的向量被视为列 而不是行,并且其内部名称将被忽略
在这里,您构造的y
仅具有内部名称-它是两个未命名的列表元素,每个元素都包含一个长度为1的矢量,其矢量元素名为a
。因此,此错误似乎是预料之中的。
如果为列表元素命名,则可以看到它的行为与所描述的一样,将向量视为列:
library(tidyverse)
y <- map(1:2, ~ c(a=.x)) %>%
set_names(c("a", "b"))
bind_rows(y)
#> # A tibble: 1 x 2
#> a b
#> <int> <int>
#> 1 1 2
通过y
提供do.call
作为参数的区别在于,它更像是编写bind_rows(c(a = 1), c(a = 2))
。这不是包含向量的列表,而是单独的向量,因此按预期按行绑定。
答案 1 :(得分:1)
bind_rows()
也会输出错误 Error: Argument 1 must have names.
。确保你没有传递给它一个矩阵。