web-dev-qa-db-ja.com

bind_rows_(x、.id)のエラー:引数1には名前が必要です

コードスニペットは次のとおりです。

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)を呼び出すと、期待どおりに機能します。

test2
# A tibble: 2 x 1
      a
  <int>
1     1
2     2

どうして?これは、dplyr 0.7.6およびpurrr 0.2.5を使用しています。 mapの代わりにmap_dfを使用すると、同じエラーで失敗します。

注:この質問が bind_rows_(x、.id)のエラー:引数1はpurrrのmap_dfを使用する名前を持たなければならない と同じであるとは思えません。

編集:この問題に対処する他の方法は、最初に明示的にデータフレームを作成することです:

y <- purrr::map(1:2, ~ data.frame(a=.x))

test1test2はエラーなしで作成され、同一になりました。

または、これは1ステップでtest2データフレームを作成します。

purrr::map_df(1:2, ~ data.frame(a=.x))
6
Robert McDonald

_bind_rows_のドキュメントから:

歴史的な理由から、ベクトルを含むリストは常にデータフレームとして扱われます。したがって、それらのベクトルは行ではなく列として扱われ、それらの内部名は無視されます

ここで、構築されたyは内部名のみを持ちます-それは名前のない2つのリスト要素で、それぞれがaという名前のベクトル要素を持つ長さ1のベクトルを含んでいます。したがって、このエラーは予想されるようです。

リスト要素に名前を付けると、ベクトルが列として扱われ、リストの要素が説明どおりに動作することがわかります。

_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))を記述することに似ていることです。これはベクトルを含むリストではなく、個別のベクトルであるため、期待どおりに行ごとにバインドします。

5
Calum You