Home > Back-end >  How to rename dataframes in a list of dataframes where the new name is stored as a value in a column
How to rename dataframes in a list of dataframes where the new name is stored as a value in a column

Time:11-05

I would like to reverse this: A solution taken from here One-liner to concatenate two data frames with a distinguishing column?

library(dplyr)
bind_rows(list(A = df1, B = df2), .id = 'id')

Here we assign the names of each data frame in a list to a column named id in each data frame in the list.

Now how can I do the reverse: E.g when the name is stored in the column called id -> to rename each dataframe in the list:

An example This is my_list:

[[1]]
# A tibble: 2 x 5
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species   
         <dbl>       <dbl>        <dbl>       <dbl> <chr>     
1          5.1         3.5          1.4         0.2 new_setoas
2          4.9         3            1.4         0.2 new_setoas

[[2]]
# A tibble: 2 x 5
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species      
         <dbl>       <dbl>        <dbl>       <dbl> <chr>        
1          6.3         3.3          6           2.5 new_virginica
2          5.8         2.7          5.1         1.9 new_virginica

[[3]]
# A tibble: 2 x 5
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species   
         <dbl>       <dbl>        <dbl>       <dbl> <chr>     
1          7           3.2          4.7         1.4 versicolor
2          6.4         3.2          4.5         1.5 versicolor


my_list <- structure(list(structure(list(Sepal.Length = c(5.1, 4.9), Sepal.Width = c(3.5, 
3), Petal.Length = c(1.4, 1.4), Petal.Width = c(0.2, 0.2), Species = c("new_setoas", 
"new_setoas")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-2L)), structure(list(Sepal.Length = c(6.3, 5.8), Sepal.Width = c(3.3, 
2.7), Petal.Length = c(6, 5.1), Petal.Width = c(2.5, 1.9), Species = c("new_virginica", 
"new_virginica")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-2L)), structure(list(Sepal.Length = c(7, 6.4), Sepal.Width = c(3.2, 
3.2), Petal.Length = c(4.7, 4.5), Petal.Width = c(1.4, 1.5), 
    Species = c("versicolor", "versicolor")), class = c("tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -2L))), ptype = structure(list(
    Sepal.Length = numeric(0), Sepal.Width = numeric(0), Petal.Length = numeric(0), 
    Petal.Width = numeric(0), Species = character(0)), class = c("tbl_df", 
"tbl", "data.frame"), row.names = integer(0)), class = c("vctrs_list_of", 
"vctrs_vctr", "list"))

Desired output:

[[new_setoas]]
# A tibble: 2 x 5
  Sepal.Length Sepal.Width Petal.Length Petal.Width 
         <dbl>       <dbl>        <dbl>       <dbl> 
1          5.1         3.5          1.4         0.2 
2          4.9         3            1.4         0.2 

[[new_virginica]]
# A tibble: 2 x 5
  Sepal.Length Sepal.Width Petal.Length Petal.Width 
         <dbl>       <dbl>        <dbl>       <dbl> 
1          6.3         3.3          6           2.5 
2          5.8         2.7          5.1         1.9 

[[versicolor]]
# A tibble: 2 x 5
  Sepal.Length Sepal.Width Petal.Length Petal.Width 
         <dbl>       <dbl>        <dbl>       <dbl> 
1          7           3.2          4.7         1.4 
2          6.4         3.2          4.5         1.5 

CodePudding user response:

names(my_list)<-lapply(my_list, FUN =  function(x) {toString(head(x["Species"],1))})
> my_list
$new_setoas
  Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
1          5.1         3.5          1.4         0.2 new_setoas
2          4.9         3.0          1.4         0.2 new_setoas

$new_virginica
  Sepal.Length Sepal.Width Petal.Length Petal.Width       Species
1          6.3         3.3          6.0         2.5 new_virginica
2          5.8         2.7          5.1         1.9 new_virginica

$versicolor
  Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
1          7.0         3.2          4.7         1.4 versicolor
2          6.4         3.2          4.5         1.5 versicolor

attr(,"ptype")
[1] Sepal.Length Sepal.Width  Petal.Length Petal.Width  Species     
<0 rows> (or 0-length row.names)
attr(,"class")
[1] "vctrs_list_of" "vctrs_vctr"    "list"

CodePudding user response:

Another option if you like purrr:

library(purrr)

map_chr(my_list, ~unique(.x$Species)) |>
  set_names()|>
  map2(my_list, ~.y)
#> $new_setoas
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
#> 1          5.1         3.5          1.4         0.2 new_setoas
#> 2          4.9         3.0          1.4         0.2 new_setoas
#> 
#> $new_virginica
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width       Species
#> 1          6.3         3.3          6.0         2.5 new_virginica
#> 2          5.8         2.7          5.1         1.9 new_virginica
#> 
#> $versicolor
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
#> 1          7.0         3.2          4.7         1.4 versicolor
#> 2          6.4         3.2          4.5         1.5 versicolor

CodePudding user response:

Maybe this works for you

setNames(lapply(my_list, "[", -5), sapply(my_list, function(x) unique(x$Species)))
$new_setoas
# A tibble: 2 × 4
  Sepal.Length Sepal.Width Petal.Length Petal.Width
         <dbl>       <dbl>        <dbl>       <dbl>
1          5.1         3.5          1.4         0.2
2          4.9         3            1.4         0.2

$new_virginica
# A tibble: 2 × 4
  Sepal.Length Sepal.Width Petal.Length Petal.Width
         <dbl>       <dbl>        <dbl>       <dbl>
1          6.3         3.3          6           2.5
2          5.8         2.7          5.1         1.9

$versicolor
# A tibble: 2 × 4
  Sepal.Length Sepal.Width Petal.Length Petal.Width
         <dbl>       <dbl>        <dbl>       <dbl>
1          7           3.2          4.7         1.4
2          6.4         3.2          4.5         1.5
  • Related