Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditionally rename columns in list, based on separate character vector stored in data.frame

I have a list of tibbles called lst:

> lst
[[1]]
# A tibble: 2 x 4
  temp1    temp2 temp3    id
  <chr>    <dbl> <dbl> <dbl>
1 Metric 1   150  1234   201
2 Metric 2   190  3456   201

[[2]]
# A tibble: 2 x 4
  temp1    temp2 temp3    id
  <chr>    <dbl> <dbl> <dbl>
1 Metric 1   190  1231   202
2 Metric 2   120  3356   202

I also have a separate tibble called df, with a column containing character vectors to rename the columns in lst:

# A tibble: 2 x 2
  colnames                                                      id
  <chr>                                                      <dbl>
1 c(' ','Ranking 1 for School A', 'Ranking 2 for School A')    201
2 c(' ', 'Ranking 1 for School B', 'Ranking 2 for School B')   202

I'm looking for a way, ideally using some form of map from purrr, to drop the id column and rename the columns for each tibble in lst, based on the values in df.

Any advice is very much appreciated. Thank you in advance.

Desired output:

[[1]]
# A tibble: 2 x 3
  ` `      `Ranking 1 for School A` `Ranking 2 for School A`
  <chr>                       <dbl>                    <dbl>
1 Metric 1                      150                     1234
2 Metric 2                      190                     3456

[[2]]
# A tibble: 2 x 3
  ` `      `Ranking 1 for School B` `Ranking 2 for School B`
  <chr>                       <dbl>                    <dbl>
1 Metric 1                      190                     1231
2 Metric 2                      120                     3356

Data:

lst <- list(structure(list(temp1 = c("Metric 1", "Metric 2"), temp2 = c(150, 
190), temp3 = c(1234, 3456), id = c(201, 201)), row.names = c(NA, 
-2L), class = c("tbl_df", "tbl", "data.frame")), structure(list(
    temp1 = c("Metric 1", "Metric 2"), temp2 = c(190, 120), temp3 = c(1231, 
    3356), id = c(202, 202)), row.names = c(NA, -2L), class = c("tbl_df", 
"tbl", "data.frame")))

df <- structure(list(colnames = c("c(' ','Ranking 1 for School A', 'Ranking 2 for School A')", 
"c(' ', 'Ranking 1 for School B', 'Ranking 2 for School B')"), 
    id = c(201, 202)), row.names = c(NA, -2L), class = c("tbl_df", 
"tbl", "data.frame"))
like image 568
Matt Avatar asked Jan 25 '23 07:01

Matt


1 Answers

Taken at facevalue, this is what I would do,

library(tidyverse)

1:length(lst) %>% map(
        .f = function(x) {
                
                # Store list
                tmp <- lst[[x]] %>% 
                        select(-"id")
                
                
                # Rename Colums
                colnames(tmp) <- paste((df[x,"colnames"])) %>%
                                    parse(text = .) %>% 
                                       eval()
                
                # Return the modified data 
                tmp
                
        }
)

Note: This, obviously, assumes that lst and the colnames are stored sequentially, such that index 1 in list uses index 1 in df[,"colnames"].

like image 193
Serkan Avatar answered Jan 30 '23 13:01

Serkan