Error in bind_rows_(x, .id) : Argument 1 must have names
From the documentation of bind_rows
:
Note that for historical reasons, lists containg vectors are always
treated as data frames. Thus their vectors are treated as columns
rather than rows, and their inner names are ignored
Here, your y
as constructed has only inner names - it is two unnamed list elements, each containing a length-one vector with the vector element named a
. So this error seems to be expected.
If you name the list elements, you can see that it behaves as described, with the vectors treated as columns:
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
The difference with supplying y
as arguments via do.call
is that it's more like writing bind_rows(c(a = 1), c(a = 2))
. This is not a list containing vectors, but separate vectors, so it binds by row as expected.
Bind_rows() error: Argument 1 must have names // Occurs after tidyverse update
The first part of your attempt gives you a list for every column irrespective of it's length.
x <- data.frame((sapply(x, c)))
str(x)
#'data.frame': 4 obs. of 3 variables:
# $ col1:List of 4
# ..$ : chr "a"
# ..$ : chr "b"
# ..$ : chr "c"
# ..$ : logi NA
# $ col2:List of 4
# ..$ : num 1
# ..$ : num 2
# ..$ : num 3
# ..$ : num 4
# $ col3:List of 4
# ..$ : chr "value1"
# ..$ : chr "value2"
# ..$ : chr "value1"
# ..$ : chr "value1" "value2"
You can unlist
the above for columns with only 1 element.
x[] <- lapply(x, function(p) if(max(lengths(p)) == 1) unlist(p) else p)
x
# col1 col2 col3
#1 a 1 value1
#2 b 2 value2
#3 c 3 value1
#4 <NA> 4 value1, value2
str(x)
#'data.frame': 4 obs. of 3 variables:
# $ col1: chr "a" "b" "c" NA
# $ col2: num 1 2 3 4
# $ col3:List of 4
# ..$ : chr "value1"
# ..$ : chr "value2"
# ..$ : chr "value1"
# ..$ : chr "value1" "value2"
R bind_rows() error: Argument 1 must have names
Is this the result you want?
First, I load the libraries and create the data, as per your question.
library(tibble)
library(purrr)
library(dplyr)
library(matrixTests)
df1 <- tibble(
var1A= rnorm(1:10) +1,
var1B= rnorm(1:10) +1,
var2A= rnorm(1:10) +2,
var2B= rnorm(1:10) +2,
var3A= rnorm(1:10) +3,
var3B= rnorm(1:10) +3)
df2 <- tibble(
var1A= rnorm(1:10) +1,
var1B= rnorm(1:10) +1,
var2A= rnorm(1:10) +2,
var2B= rnorm(1:10) +2,
var3A= rnorm(1:10) +3,
var3B= rnorm(1:10) +3)
df3 <- tibble(
var1A= rnorm(1:10) +1,
var1B= rnorm(1:10) +1,
var2A= rnorm(1:10) +2,
var2B= rnorm(1:10) +2,
var3A= rnorm(1:10) +3,
var3B= rnorm(1:10) +3)
thresholds = c(1, 2, 3)
list_dfs = c('df1','df2','df3')
Here, I unlist
the results before binding.
map(list_dfs,
function(df_name){
x <- get(df_name)
lapply(thresholds, function(i){
col_t_welch(x %>%
pull(paste0("var",i,"A")),
x %>%
pull(paste0("var",i,"B")))
})
}) %>%
unlist(recursive = FALSE) %>%
bind_rows()
which gives,
#> obs.x obs.y obs.tot mean.x mean.y mean.diff var.x var.y
#> 1 10 10 20 0.4123358 0.9386079 -0.52627205 1.2887733 1.4188697
#> 2 10 10 20 1.4848642 1.8852731 -0.40040891 0.7594906 1.9971866
#> 3 10 10 20 2.9905342 3.1454473 -0.15491307 0.9501264 0.6863846
#> 4 10 10 20 1.2409187 0.9453490 0.29556964 1.8969049 0.5213807
#> 5 10 10 20 2.0823664 2.3150223 -0.23265591 0.5171046 0.6771720
#> 6 10 10 20 3.0354769 2.2958400 0.73963696 0.8915344 1.1509940
#> 7 10 10 20 0.5546491 0.8868825 -0.33223340 0.6404670 0.4313640
#> 8 10 10 20 2.9031533 2.5956085 0.30754479 1.1602239 1.6080605
#> 9 10 10 20 3.1435888 3.1988889 -0.05530018 1.7926813 0.4374122
#> stderr df statistic pvalue conf.low conf.high alternative
#> 1 0.5203502 17.95854 -1.0113806 0.3252679 -1.6196681 0.5671240 two.sided
#> 2 0.5250407 14.98023 -0.7626246 0.4575287 -1.5196353 0.7188175 two.sided
#> 3 0.4045381 17.54432 -0.3829381 0.7063657 -1.0064012 0.6965751 two.sided
#> 4 0.4917607 13.59994 0.6010437 0.5576963 -0.7620703 1.3532096 two.sided
#> 5 0.3455831 17.68236 -0.6732272 0.5095070 -0.9596350 0.4943232 two.sided
#> 6 0.4519434 17.71416 1.6365699 0.1193625 -0.2109603 1.6902343 two.sided
#> 7 0.3273883 17.34004 -1.0147992 0.3241530 -1.0219320 0.3574652 two.sided
#> 8 0.5261449 17.54094 0.5845249 0.5663102 -0.7999219 1.4150114 two.sided
#> 9 0.4722387 13.14519 -0.1171022 0.9085494 -1.0743655 0.9637651 two.sided
#> mean.null conf.level
#> 1 0 0.95
#> 2 0 0.95
#> 3 0 0.95
#> 4 0 0.95
#> 5 0 0.95
#> 6 0 0.95
#> 7 0 0.95
#> 8 0 0.95
#> 9 0 0.95
Created on 2019-03-21 by the reprex package (v0.2.1)
Error in bind_rows_(x, .id) : Argument 1 must have names using map_df in purrr
The problem is that when it binds the rows, it cannot bind with NA
. To fix this just use data.frame()
rather than NA
.
Here's a simpler example of the problem.
library('dplyr')
library('purrr')
try_filter <- function(df) {
tryCatch(
df %>%
filter(Sepal.Length == 4.6),
error = function(e) NA)
}
map_df(
list(iris, NA, iris),
try_filter)
#> Error in bind_rows_(x, .id) : Argument 1 must have names
The solution is to replace NA
with data.frame()
.
try_filter <- function(df) {
tryCatch(
df %>%
filter(Sepal.Length == 4.6),
error = function(e) data.frame())
}
map_df(
list(iris, NA, iris),
try_filter)
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1 4.6 3.1 1.5 0.2 setosa
#> 2 4.6 3.4 1.4 0.3 setosa
#> 3 4.6 3.6 1.0 0.2 setosa
#> 4 4.6 3.2 1.4 0.2 setosa
#> 5 4.6 3.1 1.5 0.2 setosa
#> 6 4.6 3.4 1.4 0.3 setosa
#> 7 4.6 3.6 1.0 0.2 setosa
#> 8 4.6 3.2 1.4 0.2 setosa
pmap purrr error: Argument 1 must have names
The problem occurs for regular data frames too so to reduce this to the essentials start a new R session, get rid of the data.table part and use the input shown where we have a 3x4 data.frame so that we don't confuse rows and columns. Also note that pmap_dfr(sum, d)
is the same as pmap(sum, d) %>% bind_rows
and it is in the bind_rows
step that the problem occurs.
library(dplyr)
library(purrr)
# test input
temp.df <- data.frame(a = 1:3, b = 1:3, c = 1:3, z = 1:3)
rownames(temp.df) <- LETTERS[1:3]
d <- 10
out <- temp.df %>% pmap(sum, d) # this works
out %>% bind_rows
## Error: Argument 1 must have names
The problem, as the error states, is that out
has no names and it seems it will not provide default names for the result. For example, this will work -- I am not suggesting that you necessarily do this but just trying to illustrate why it does not work by showing minimal changes that make it work:
temp.df %>% pmap(sum, d) %>% set_names(rownames(temp.df)) %>% bind_rows
## # A tibble: 1 x 3
## A B C
## <dbl> <dbl> <dbl>
## 1 14 18 22
or this could be written like this to avoid writing temp.df
twice:
temp.df %>% { set_names(pmap(., sum, d), rownames(.)) } %>% bind_rows
I think we can conclude that pmap_dfr
is just not the right function to use here.
Base R
Of course, this is all trivial in base R as you can do this:
rowSums(temp.df) + d
## A B C
## 14 18 22
or more generally:
as.data.frame.list(apply(temp.df, 1, sum, d))
## A B C
## 14 18 22
or
as.data.frame.list(Reduce("+", temp.df) + d)
## X14 X18 X22
##1 14 18 22
data.table
In data.table we can write:
library(data.table)
DT <- as.data.table(temp.df)
DT[, as.list(rowSums(.SD) + d)]
## V1 V2 V3
## 1: 14 18 22
DT[, as.list(apply(.SD, 1, sum, d))]
## V1 V2 V3
## 1: 14 18 22
Also note that using data.table directly tends to be faster than sticking another level on top of it so if you thought you were getting the benefit of data.table's speed by using it with dplyr and purrr you likely aren't.
How to resolve error: Argument 1 must have names when using map( ) pluck( ) in R to list( )?
To bind_rows()
, you just need to convert the list of vectors into a list of dataframe
beforehand. So, you could do:
Reprex
- Code
library(purrr)
library(dplyr)
list(list(result="0001"),list(result="0002")) %>%
purrr::map(pluck, 'result') %>%
purrr::map(., ~ data.frame(results = .)) %>%
bind_rows()
- Output
#> results
#> 1 0001
#> 2 0002
Created on 2022-03-04 by the reprex package (v2.0.1)
Related Topics
Why Does Mapply Not Return Date-Objects
How to Create a Bar and Line Plot with R Dygraphs
Why Does As.Matrix Add Extra Spaces When Converting Numeric to Character
R: Convert Date from Character to Datetime
Warning "The Condition Has Length > 1 and Only the First Element Will Be Used"
Can Not Connect Postgresql(Over Ssl) with Rpostgresql on Windows
Topic Models: Cross Validation with Loglikelihood or Perplexity
What Is the Practical Difference Between Data.Frame and Data.Table in R
R Shiny Loop to Display Multiple Plots
Parsing Iso8601 Date and Time Format in R
R - Svd() Function - Infinite or Missing Values in 'X'
Rstudio Calls Source() When Saving Script
Keep Only Groups of Data with Multiple Observations
Filling in a New Column Based on a Condition in a Data Frame