Search code examples
rlistnames

How to change colnames of nested dataframes in a list of lists


I have a list of data frames, the names of which are shown below:

lapply(L2, function(x) {print(names(x))}):

$D1
[1] "TP1.adjPVal" "TP1.Log2FC" 

$D2
[1] "TP2.adjPVal" "TP2.Log2FC" 

$D3
[1] "TP3.adjPVal" "TP3.Log2FC" 

$D7
[1] "TP7.adjPVal" "TP7.Log2FC" 

$D14
[1] "TP14.adjPVal" "TP14.Log2FC" 

I would like to change all the TP into D.

I have tried the following codes from searching stackoverflow but am struggling to reach my goal.

lapply(L2, function(x) {gsub(x = names(x), pattern = 'TP', replacement = 'D')})

setNames(L2$D1, tp$D1)

lapply(L2, function(x) { colnames(x) <- gsub(x = colnames(x), pattern = 'TP', replacement = 'D')})

Any help in this issue would be most welcome.


Solution

  • We need to return the x i.e. the data.frame. In the OP's code, it is only doing the assignment. Also, as the 'TP' is at the start of the string, can use ^ to specify the start and we don't need gsub instead use sub (for single substitution)

    lapply(L2, function(x) {
           colnames(x) <- sub(x = colnames(x), pattern = '^TP', replacement = 'D')
          x}
           )
    

    Or another option is setNames. In this case, we can do the assignment on the fly as setNames internally does the assignment

    lapply(L2, function(x) setNames(x, 
            sub(x = colnames(x), pattern = '^TP', replacement = 'D')))
    

    Also, if we use tidyverse

    library(tidyverse)
    map(L2, ~ .x %>%
                rename_at(vars(starts_with("TP")), ~ str_replace(., "^TP", "D")))