What is the fastest way to get names within a list to a column within a data frame?

I have this list:

my_list <- list(
  option1 = data.frame(
    x = rnorm(5),
    y = sample(1:10, 5)
  ),
  option2 = data.frame(
    x = rnorm(5),
    y = sample(1:10, 5)
  )
)

How do I create a column within each data frame with the 'option' variable? E.g.:

$option1
             x y  option
1 -1.557148459 1 option1
2  0.806085447 5 option1
3 -0.300248656 3 option1
4  0.027685959 4 option1
5  0.009803611 8 option1

$option2
           x y  option
1 -1.0855301 6 option2
2  0.6982276 7 option2
3 -0.2026420 1 option2
4  0.3478627 2 option2
5  0.9958502 9 option2

And then as you may have guessed, bind the data frames together?

If you allow `base-r` solutions, here's a way to do it:
my_list <- list(option1 = data.frame(x = rnorm(n = 5),
                                     y = sample(x = 1:10,
                                                size = 5)),
                option2 = data.frame(x = rnorm(5),
                                     y = sample(1:10, 5)))

output_df <- do.call(what = rbind,
                     args = Map(f = cbind,
                                my_list,
                                option = list("option1", "option2")))
row.names(x = output_df) <- NULL

output_df
#>              x  y  option
#> 1  -0.07151219  8 option1
#> 2  -0.64308030  9 option1
#> 3   0.24600467  5 option1
#> 4   2.95384811  7 option1
#> 5  -0.95911835  3 option1
#> 6  -1.02366867  1 option2
#> 7   0.07269563  9 option2
#> 8   1.11685915 10 option2
#> 9   0.26242290  3 option2
#> 10  0.34732845  5 option2

Created on 2019-04-25 by the reprex package (v0.2.1)


A purr solution:

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(purrr)

my_list <- list(option1 = data.frame(x = rnorm(n = 5),
                                     y = sample(x = 1:10,
                                                size = 5)),
                option2 = data.frame(x = rnorm(5),
                                     y = sample(1:10, 5)))

map2_df(.x = my_list,
        .y = names(my_list),
        .f = ~ mutate(.x, option = .y))
#>             x  y  option
#> 1   0.1539759  1 option1
#> 2   0.7819265  9 option1
#> 3   1.2066628 10 option1
#> 4   0.3484192  5 option1
#> 5   0.5396239  2 option1
#> 6   1.2089579  6 option2
#> 7  -0.1286908  8 option2
#> 8   0.7777358  2 option2
#> 9   2.8864360  5 option2
#> 10 -0.5604640  9 option2

Created on 2019-04-25 by the reprex package (v0.2.1)

2 Likes

If the aim is to row bind at the end you could be interested by

dplyr::bind_rows(my_list, .id="option")
8 Likes

Since the new variables are static you can add them in-place directly.

my_list$option1$id='option1'
my_list$option2$id='option2'

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.