bind_rows_(x, .id) 中的错误:参数1必须具有名称。

26

这里是一段代码示例:

y <- purrr::map(1:2, ~ c(a=.x))
test1 <- dplyr::bind_rows(y)
test2 <- do.call(dplyr::bind_rows, y)

第一次调用bind_rowstest1)会生成错误。

Error in bind_rows_(x, .id) : Argument 1 must have names

然而,使用do.call来调用bind_rowstest2),则可以按预期工作:

Translated text:

However, using do.call to invoke bind_rows (test2) works as expected:

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))

test1test2现已无误地创建,并且它们是相同的。

或者,这将一步创建test2数据框:

purrr::map_df(1:2, ~ data.frame(a=.x))
2个回答

27

bind_rows的文档中可以得知:

值得注意的是,由于历史原因,包含向量的列表总是被视为数据框。因此它们的向量被视为列而不是行,并且它们的内部名称被忽略。

在这里,您构建的y仅具有内部名称 - 它是两个未命名列表元素,每个元素都包含一个长度为一的向量,其中向量元素命名为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

使用do.call通过将y作为参数提供的区别在于它更像是写bind_rows(c(a = 1), c(a = 2))。这不是包含向量的列表,而是单独的向量,因此会按行绑定,如预期所示。


1
谢谢。但是“内部名称”的定义是什么?这是指向量的名称属性吗?这个术语在R-ints、R-lang或R-intro中都没有出现过。 - Robert McDonald
我相信这里是这样的。我认为它不应该表示除了列表元素内部事物的名称之外的任何内容,而不是元素的名称。但因为我们正在讨论一个向量列表,这意味着向量的名称。 - Calum You
1
你的回答还解释了为什么在这种情况下rbind和cbind似乎是相反的。我没有提到它,但它非常令人困惑。R语言中有许多曲折的边缘和黑暗的角落 :-) - Robert McDonald

6

bind_rows()函数如果你试图把一个矩阵绑定到另一个数据框,而不是将其绑定到数据框,则会输出错误信息Error:Argument 1 must have names。,请确保不要传递矩阵。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接