4

I want to add a prefix to each column (except the first) in each dataframe in a list of dataframe. I have been taking the approach that I would used for a single dataframe and trying to use both lapply and Map without success.

I also want change the the first column of each dataframe by adding the name of the dataframe as a prefix to the existing name

A snippet of my list of dataframes

l1 <- list(Fe = structure(list(Determination_No = 1:6, `2` = c(55.94, 
55.7, 56.59, 56.5, 55.98, 55.93), `3` = c(56.83, 56.54, 56.18, 
56.5, 56.51, 56.34), `4` = c(56.39, 56.43, 56.53, 56.31, 56.47, 
56.35), `5` = c(56.32, 56.29, 56.31, 56.32, 56.39, 56.32), `7` = c(56.48, 
56.4, 56.54, 56.43, 56.73, 56.62), `8` = c(56.382, 56.258, 56.442, 
56.258, 56.532, 56.264), `10` = c(56.3, 56.5, 56.2, 56.5, 56.7, 
56.5), `12` = c(56.11, 56.46, 56.1, 56.35, 56.36, 56.37)), class = "data.frame", row.names = c(NA, 
-6L)), SiO2 = structure(list(Determination_No = 1:6, `2` = c(7.63, 
7.65, 7.73, 7.67, 7.67, 7.67), `3` = c(7.84, 7.69, 7.59, 7.77, 
7.74, 7.64), `4` = c(7.67, 7.74, 7.62, 7.81, 7.66, 7.8), `5` = c(7.91, 
7.84, 7.96, 7.87, 7.84, 7.92), `7` = c(7.77, 7.83, 7.76, 7.78, 
7.65, 7.74), `8` = c(7.936, 7.685, 7.863, 7.838, 7.828, 7.767
), `10` = c(7.872684992, 7.851291827, 7.872684992, 7.722932832, 
7.680146501, 7.615967003), `12` = c(7.64, 7.71, 7.71, 7.65, 7.82, 
7.68)), class = "data.frame", row.names = c(NA, -6L)), Al2O3 = structure(list(
    Determination_No = 1:6, `2` = c(2.01, 2.02, 2.03, 2.01, 2.02, 
    2), `3` = c(2.01, 2.01, 2, 2.02, 2.02, 2.03), `4` = c(2, 
    2.03, 1.99, 2.01, 2.01, 2.01), `5` = c(2.02, 2.02, 2.05, 
    2.03, 2.02, 2.03), `7` = c(1.88, 1.9, 1.89, 1.88, 1.88, 1.87
    ), `8` = c(2.053, 2.044, 2.041, 2.038, 2.008, 2.02), `10` = c(2.002830415, 
    2.021725042, 2.021725042, 1.983935789, 2.002830415, 2.021725042
    ), `12` = c(2.09, 2.05, 1.96, 2.09, 2.06, 2.02)), class = "data.frame", row.names = c(NA, 
-6L)))

I have tried the following


colnames(l1[-1]) <- lapply(l1[-1],paste0("Lab-",colnames(l1[-1])))

colnames(l1[-1]) <- Map(paste("Lab",colnames(l1[-1]),sep=" "),l1[-1])

Using either solution I get the following error message

Error in get(as.character(FUN), mode = "function", envir = envir):
  object 'Lab-' of mode 'function' was not found

3 Answers 3

2

In tidyverse, we can use imap with rename_with :

library(dplyr)
library(purrr)

imap(l1, ~.x %>% 
  rename_with(function(x) c(paste(.y, x[1], sep = '_'), paste0('lab_', x[-1]))))

#$Fe
#  Fe_Determination_No lab_2 lab_3 lab_4 lab_5 lab_7  lab_8 lab_10 lab_12
#1                   1 55.94 56.83 56.39 56.32 56.48 56.382   56.3  56.11
#2                   2 55.70 56.54 56.43 56.29 56.40 56.258   56.5  56.46
#3                   3 56.59 56.18 56.53 56.31 56.54 56.442   56.2  56.10
#4                   4 56.50 56.50 56.31 56.32 56.43 56.258   56.5  56.35
#5                   5 55.98 56.51 56.47 56.39 56.73 56.532   56.7  56.36
#6                   6 55.93 56.34 56.35 56.32 56.62 56.264   56.5  56.37

3$SiO2
#  SiO2_Determination_No lab_2 lab_3 lab_4 lab_5 lab_7 lab_8   lab_10 lab_12
#1                     1  7.63  7.84  7.67  7.91  7.77 7.936 7.872685   7.64
#2                     2  7.65  7.69  7.74  7.84  7.83 7.685 7.851292   7.71
#3                     3  7.73  7.59  7.62  7.96  7.76 7.863 7.872685   7.71
#4                     4  7.67  7.77  7.81  7.87  7.78 7.838 7.722933   7.65
#5                     5  7.67  7.74  7.66  7.84  7.65 7.828 7.680147   7.82
#6                     6  7.67  7.64  7.80  7.92  7.74 7.767 7.615967   7.68

#$Al2O3
#  Al2O3_Determination_No lab_2 lab_3 lab_4 lab_5 lab_7 lab_8   lab_10 lab_12
#1                      1  2.01  2.01  2.00  2.02  1.88 2.053 2.002830   2.09
#2                      2  2.02  2.01  2.03  2.02  1.90 2.044 2.021725   2.05
#3                      3  2.03  2.00  1.99  2.05  1.89 2.041 2.021725   1.96
#4                      4  2.01  2.02  2.01  2.03  1.88 2.038 1.983936   2.09
#5                      5  2.02  2.02  2.01  2.02  1.88 2.008 2.002830   2.06
#6                      6  2.00  2.03  2.01  2.03  1.87 2.020 2.021725   2.02 

Or in base R with Map :

Map(function(x, y) {
  names(x) <- c(paste(y, names(x)[1], sep = '_'), paste0('lab_', names(x[-1])))
  x
}, l1, names(l1))
Sign up to request clarification or add additional context in comments.

5 Comments

Dear Ronak Shah, I am so sorry to interrupt. May I ask in case I wanted to rename all the columns except the first one why this code returns an error, I just can't spot the problem: l1 %>% map(~ .x %>% rename_with(~ str_c("Lab", names(.x)[-1], sep = "_"), -c(1))) . Thank you very much in advance.
@Ronak Shah. Out of curiosity why was my solution for all but the first column not working?
@AnoushiravanR You don't need names in rename_with. Try l1 %>% map(~ .x %>% rename_with(~str_c("Lab", ., sep = "_"), -1))
@Spooked You cannot do colnames(l1[-1]) <- .... on a list. It would work only on dataframes.
@RonakShah Thank you so much. I really can't thank you enough. It was a subtle point.
0

Using replace and setNames in lapply.

> lapply(l1, \(x) setNames(x, replace(names(x), -1, paste0('lab_', names(x)[-1]))))
$Fe
  Determination_No lab_2 lab_3 lab_4 lab_5 lab_7  lab_8 lab_10 lab_12
1                1 55.94 56.83 56.39 56.32 56.48 56.382   56.3  56.11
2                2 55.70 56.54 56.43 56.29 56.40 56.258   56.5  56.46
3                3 56.59 56.18 56.53 56.31 56.54 56.442   56.2  56.10
4                4 56.50 56.50 56.31 56.32 56.43 56.258   56.5  56.35
5                5 55.98 56.51 56.47 56.39 56.73 56.532   56.7  56.36
6                6 55.93 56.34 56.35 56.32 56.62 56.264   56.5  56.37

$SiO2
  Determination_No lab_2 lab_3 lab_4 lab_5 lab_7 lab_8   lab_10 lab_12
1                1  7.63  7.84  7.67  7.91  7.77 7.936 7.872685   7.64
2                2  7.65  7.69  7.74  7.84  7.83 7.685 7.851292   7.71
3                3  7.73  7.59  7.62  7.96  7.76 7.863 7.872685   7.71
4                4  7.67  7.77  7.81  7.87  7.78 7.838 7.722933   7.65
5                5  7.67  7.74  7.66  7.84  7.65 7.828 7.680147   7.82
6                6  7.67  7.64  7.80  7.92  7.74 7.767 7.615967   7.68

$Al2O3
  Determination_No lab_2 lab_3 lab_4 lab_5 lab_7 lab_8   lab_10 lab_12
1                1  2.01  2.01  2.00  2.02  1.88 2.053 2.002830   2.09
2                2  2.02  2.01  2.03  2.02  1.90 2.044 2.021725   2.05
3                3  2.03  2.00  1.99  2.05  1.89 2.041 2.021725   1.96
4                4  2.01  2.02  2.01  2.03  1.88 2.038 1.983936   2.09
5                5  2.02  2.02  2.01  2.02  1.88 2.008 2.002830   2.06
6                6  2.00  2.03  2.01  2.03  1.87 2.020 2.021725   2.02

Comments

0

Similar base R approach using names.

l1 = lapply(l1, \(.) { names(.)[-1] = paste0('lab_', names(.)[-1]); . }) 
# see help('|>')
> l1
$Fe
 Determination_No lab_2 lab_3 lab_4 lab_5 lab_7  lab_8 lab_10 lab_12
1                1 55.94 56.83 56.39 56.32 56.48 56.382   56.3  56.11
2                2 55.70 56.54 56.43 56.29 56.40 56.258   56.5  56.46
3                3 56.59 56.18 56.53 56.31 56.54 56.442   56.2  56.10
4                4 56.50 56.50 56.31 56.32 56.43 56.258   56.5  56.35
5                5 55.98 56.51 56.47 56.39 56.73 56.532   56.7  56.36
6                6 55.93 56.34 56.35 56.32 56.62 56.264   56.5  56.37

$SiO2
 Determination_No lab_2 lab_3 lab_4 lab_5 lab_7 lab_8   lab_10 lab_12
1                1  7.63  7.84  7.67  7.91  7.77 7.936 7.872685   7.64
2                2  7.65  7.69  7.74  7.84  7.83 7.685 7.851292   7.71
3                3  7.73  7.59  7.62  7.96  7.76 7.863 7.872685   7.71
4                4  7.67  7.77  7.81  7.87  7.78 7.838 7.722933   7.65
5                5  7.67  7.74  7.66  7.84  7.65 7.828 7.680147   7.82
6                6  7.67  7.64  7.80  7.92  7.74 7.767 7.615967   7.68

$Al2O3
 Determination_No lab_2 lab_3 lab_4 lab_5 lab_7 lab_8   lab_10 lab_12
1                1  2.01  2.01  2.00  2.02  1.88 2.053 2.002830   2.09
2                2  2.02  2.01  2.03  2.02  1.90 2.044 2.021725   2.05
3                3  2.03  2.00  1.99  2.05  1.89 2.041 2.021725   1.96
4                4  2.01  2.02  2.01  2.03  1.88 2.038 1.983936   2.09
5                5  2.02  2.02  2.01  2.02  1.88 2.008 2.002830   2.06
6                6  2.00  2.03  2.01  2.03  1.87 2.020 2.021725   2.02

Is there a good reason to not rbind in a single data.frame? Explicitly written

l2 =
  do.call(l1, what='rbind') |>
  ( \(.) { names(.)[-1] = paste0('lab_', names(.)[-1]); . } )() |> 
  ( \(.) transform(., formula=sub('\\..*', '', row.names(.))) )() |>
  `row.names<-`(NULL)
> str(l2)
'data.frame':  18 obs. of  10 variables:
$ Determination_No: int  1 2 3 4 5 6 1 2 3 4 ...
$ lab_2           : num  55.9 55.7 56.6 56.5 56 ...
$ lab_3           : num  56.8 56.5 56.2 56.5 56.5 ...
$ lab_4           : num  56.4 56.4 56.5 56.3 56.5 ...
$ lab_5           : num  56.3 56.3 56.3 56.3 56.4 ...
$ lab_7           : num  56.5 56.4 56.5 56.4 56.7 ...
$ lab_8           : num  56.4 56.3 56.4 56.3 56.5 ...
$ lab_10          : num  56.3 56.5 56.2 56.5 56.7 ...
$ lab_12          : num  56.1 56.5 56.1 56.4 56.4 ...
$ formula         : chr  "Fe" "Fe" "Fe" "Fe" ...

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.