How to change colnames based on name of the list?

Viewed 53

I am learning R and I have a simple question of how to change a specific colnames based on the name of the list. For example, I have a list Combined:

Combined = list(L1 = mtcars[1:3,], L2 = mtcars[11:13,])

I wanted to change the 5th column to "L1" and "L2", respectively, like

$L1
                   mpg cyl  disp  hp   L1    wt  qsec vs am gear carb
Mazda RX4         21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag     21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
Datsun 710        22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1

$L2
                     mpg cyl  disp  hp   L2    wt  qsec vs am gear carb
Merc 280C           17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3

So I tried

lapply(Combined, function(x) {colnames(x)[5] <- names(x); x}) 

But it did not work. Can anyone help? Thanks!

2 Answers

Here is one option with imap with rename_at. imap uses map2 to return both the value in .x and the names of the list in .y. Then, we just need the position of the column to rename it and this can be done with rename_at (which takes either index or name as string)

library(purrr)
imap(Combined, ~ {nm1 <- .y
           .x %>% 
                rename_at(5,  ~nm1)
    })

Or in base R with Map

Map(function(dat, nm) {names(dat)[5] <- nm; dat}, Combined, names(Combined))
#$L1
#               mpg cyl disp  hp   L1    wt  qsec vs am gear carb
#Mazda RX4     21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
#Mazda RX4 Wag 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
#Datsun 710    22.8   4  108  93 3.85 2.320 18.61  1  1    4    1

#$L2
#            mpg cyl  disp  hp   L2   wt qsec vs am gear carb
#Merc 280C  17.8   6 167.6 123 3.92 3.44 18.9  1  0    4    4
#Merc 450SE 16.4   8 275.8 180 3.07 4.07 17.4  0  0    3    3
#Merc 450SL 17.3   8 275.8 180 3.07 3.73 17.6  0  0    3    3

Here is another base R option with lapply

Combined [] <- lapply(
  seq_along(Combined),
  function(k) {
    setNames(
      Combined[[k]],
      replace(names(Combined[[k]]), 5, names(Combined)[k])
    )
  }
)

such that

> Combined
$L1
               mpg cyl disp  hp   L1    wt  qsec vs am gear carb
Mazda RX4     21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
Datsun 710    22.8   4  108  93 3.85 2.320 18.61  1  1    4    1

$L2
            mpg cyl  disp  hp   L2   wt qsec vs am gear carb
Merc 280C  17.8   6 167.6 123 3.92 3.44 18.9  1  0    4    4
Merc 450SE 16.4   8 275.8 180 3.07 4.07 17.4  0  0    3    3
Merc 450SL 17.3   8 275.8 180 3.07 3.73 17.6  0  0    3    3
Related