Reputation: 1489
I have a named List
of data.frames. I was wondering how to convert the name ("bar1"
,...,"bar4"
) of each element List
as a column next to each data.frame?
My final desired_output
is shown below.
List <- list(bar1=data.frame(study="A",sd = 1), bar2=data.frame(study=c("B","C"),sd=2:3),
bar3=data.frame(study="Z",sd = 4), bar4=data.frame(study="H",sd=5))
# desired_output:
"
study sd id
A 1 bar1
B 2 bar2
C 3 bar2
Z 4 bar3
H 5 bar4
"
Upvotes: 1
Views: 1335
Reputation: 16876
Here is a base R option using Map
:
do.call(rbind, unname(Map(cbind, id = names(List), List)))
Output
id study sd
1 bar1 A 1
2 bar2 B 2
3 bar2 C 3
4 bar3 Z 4
5 bar4 H 5
Another option is to use rbindlist
from data.table
:
rbindlist(List, idcol = "id")
# id study sd
#1: bar1 A 1
#2: bar2 B 2
#3: bar2 C 3
#4: bar3 Z 4
#5: bar4 H 5
Upvotes: 3
Reputation: 1154
When I think of iterating over a vector I think of the map
functions in purrr
. In this case, map2()
iterates over multiple arguments simultaneously. I grabbed the names of the list elements and stored them in a vector, n
:
n <- names(List)
I then iterated over List
and n
at the same time, calling cbind()
to add a variable (i.e., column) to each data frame:
map2(List, n, ~ cbind(.x, Name = .y))
Output:
$bar1 study sd Name 1 A 1 bar1 $bar2 study sd Name 1 B 2 bar2 2 C 3 bar2 $bar3 study sd Name 1 Z 4 bar3 $bar4 study sd Name 1 H 5 bar4
We can collapse List
to a single data frame with a call to bind_rows()
:
result <- map2(List, n, ~ cbind(.x, Name = .y))
bind_rows(result)
Output:
study sd Name 1 A 1 bar1 2 B 2 bar2 3 C 3 bar2 4 Z 4 bar3 5 H 5 bar4
Taken as one statement that would be:
map2(List, names(List), ~ cbind(.x, Name = .y)) %>%
bind_rows()
Upvotes: 0
Reputation: 206546
The dplyr::bind_rows
function has an .id=
parameter that you can use to create a column with the names from the list of data.frames you pass in. You can just do
bind_rows(List, .id="id")
Upvotes: 4
Reputation: 11346
data.frame(do.call(rbind, List),
id = rep.int(names(List), vapply(List, nrow, 0L)),
row.names = NULL)
## study sd id
## 1 A 1 bar1
## 2 B 2 bar2
## 3 C 3 bar2
## 4 Z 4 bar3
## 5 H 5 bar4
Upvotes: 1