Voici un extrait de code:
y <- purrr::map(1:2, ~ c(a=.x))
test1 <- dplyr::bind_rows(y)
test2 <- do.call(dplyr::bind_rows, y)
Le premier appel à bind_rows
(test1
) génère l'erreur
Error in bind_rows_(x, .id) : Argument 1 must have names
En utilisant do.call
invoquer bind_rows
(test2
), d'autre part, fonctionne comme prévu:
test2
# A tibble: 2 x 1
a
<int>
1 1
2 2
Pourquoi? Cela utilise dplyr 0.7.6 et purrr 0.2.5. Si j'utilise map_df
au lieu de map
, il échoue avec la même erreur.
Remarque: Il ne me semble pas que cette question soit la même que erreur dans bind_rows_ (x, .id): l'argument 1 doit avoir des noms utilisant map_df dans purrr .
EDIT: L'autre façon de résoudre ce problème est de créer explicitement une trame de données en premier lieu:
y <- purrr::map(1:2, ~ data.frame(a=.x))
test1
et test2
sont maintenant créés sans erreur et sont identiques.
Alternativement, cela crée le test2
trame de données en une seule étape:
purrr::map_df(1:2, ~ data.frame(a=.x))
À partir de la documentation de bind_rows
:
Notez que pour des raisons historiques, les listes contenant des vecteurs sont toujours traitées comme des trames de données. Ainsi, leurs vecteurs sont traités comme des colonnes plutôt que des lignes, et leurs noms internes sont ignorés
Ici, votre y
tel qu'il est construit n'a que des noms internes - il s'agit de deux éléments de liste sans nom, chacun contenant un vecteur de longueur un avec l'élément vectoriel nommé a
. Donc, cette erreur semble être attendue.
Si vous nommez les éléments de la liste, vous pouvez voir qu'il se comporte comme décrit, avec les vecteurs traités comme des colonnes:
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
La différence avec la fourniture de y
comme arguments via do.call
Est que cela ressemble plus à l'écriture de bind_rows(c(a = 1), c(a = 2))
. Ce n'est pas une liste contenant des vecteurs, mais des vecteurs séparés, donc elle se lie par ligne comme prévu.