4

I have a list containing multiple data frames, and each list element has a unique name. The structure is similar to this dummy data

a <- data.frame(z = rnorm(20), y = rnorm(20))
b <- data.frame(z = rnorm(30), y = rnorm(30))
c <- data.frame(z = rnorm(40), y = rnorm(40))
d <- data.frame(z = rnorm(50), y = rnorm(50))

my.list <- list(a,b,c,d)
names(my.list) <- c("a","b","c","d")

I want to create a column in each of the data frames that has the name of it's respective list element. My goal is to merge all the list element into a single data frame, and know which data frame they came from originally. The end result I'm looking for is something like this:

            z           y group
1   0.6169132  0.09803228     a
2   1.1610584  0.50356131     a
3   0.6399438  0.84810547     a
4   1.0878453  1.00472105     b
5  -0.3137200 -1.20707112     b
6   1.1428834  0.87852556     b
7  -1.0651735 -0.18614224     c
8   1.1629891 -0.30184443     c
9  -0.7980089 -0.35578381     c
10  1.4651651 -0.30586852     d
11  1.1936547  1.98858128     d
12  1.6284174 -0.17042835     d

My first thought was to use mutate to assign the list element name to a column in each respective data frame, but it appears that when used within lapply, names() refers to the column names, not the list element names

test <- lapply(my.list, function(x)  mutate(x, group = names(x)))

   Error: Column `group` must be length 20 (the number of rows) or one, not 2

Any suggestions as to how I could approach this problem?

2 Answers 2

6

there is no need to mutate just bind using dplyr's bind_rows

library(tidyverse)
my.list %>% 
  bind_rows(.id = "groups")

Obviously requires that the list is named.

Sign up to request clarification or add additional context in comments.

1 Comment

This answer solution is simple and does exactly what I wanted - thanks! Maybe you can answer this question too....I've never understood the syntax where some arguments have a . in front of them like .id. Do you know why it's called .id and not just id?
4

We can use Map from base R:

Map(cbind, my.list, group = names(my.list))

Or with imap from purrr:

library(dplyr)
library(purrr)
imap(my.list, ~ .x %>% mutate(group = .y))

Or if the intention is to create a single data.frame

library(data.table)
rbindlist(my.list. idcol = 'groups')

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.