5

Given a list of dataframes l as follows:

l <- list(a = data.frame(a_1 = c(11, 12),
                        a_2 = c(13, 14)),
          b = data.frame(b_1 = c(21, 22),
                        b_2 = c(23, 24)),
          c = data.frame(c_1 = c(31, 32),
                          c_2 = c(33, 34)))
print(l)

Out:

enter image description here

Now I would like to append a new column new_col using the name of each dataframe:

l[['a']]$new_col = 'a'
l[['b']]$new_col = 'b'
l[['c']]$new_col = 'c'

I wonder how to append column for each dataframe by using names(l) which is [1] "a" "b" "c" automatically? Thanks.

The final result will like this:

enter image description here

ah bon
  • 9,293
  • 12
  • 65
  • 148

2 Answers2

6

Method 1: tidyverse solution with map2

library(tidyverse)
map2(l, names(l), ~ mutate(.x, new_col = .y))

Output:

$a
  a_1 a_2 new_col
1  11  13       a
2  12  14       a

$b
  b_1 b_2 new_col
1  21  23       b
2  22  24       b

$c
  c_1 c_2 new_col
1  31  33       c
2  32  34       c

Method 2: for loop solution

(l gives the above output):

for(i in 1:length(names(l))) {
  l[[i]]$new_col <- names(l)[i]
}
Rory S
  • 1,278
  • 5
  • 17
  • 1
    Thanks, it works. Is it possible to using for loop such as `for(i in l) {...}`? – ah bon Jul 29 '21 at 08:35
  • 1
    @ahbon absolutely: just edited my answer to add a for loop solution. `map2` does the same thing and is cleaner in my opinion, but use whichever you like. – Rory S Jul 29 '21 at 08:39
2

Or with mapply():

mapply(cbind, l, "new_col"=names(l), SIMPLIFY=F)
KacZdr
  • 1,267
  • 3
  • 8
  • 23