Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create new column of from list using each item's name

Tags:

r

dplyr

purrr

I have a list of dataframes. I'd like to loop through them using purrr and do some analysis. Part of the analysis includes renaming a variable according to the name of the list item. This allows me to properly merge the files into a single dataframe. I'm a bit stuck as to how to go about accomplishing this.

    library(tidyverse)

# Get names of columns

df <- mtcars %>% 
  as_tibble() %>% 
  select(1:5)

mtcars_names <- df %>% 
  names()

# Split into many dataframes based on columns
mtcars_ls <- df %>% 
  gather(key, value) %>%
  split(.$key)


map2(mtcars_ls, mtcars_names, function(x, y){
  x %>% 
    rename(y = value)
})
#> $cyl
#> # A tibble: 32 x 2
#>    key       y
#>    <chr> <dbl>
#>  1 cyl       6
#>  2 cyl       6
#>  3 cyl       4
#>  4 cyl       6
#>  5 cyl       8
#>  6 cyl       6
#>  7 cyl       8
#>  8 cyl       4
#>  9 cyl       4
#> 10 cyl       6
#> # … with 22 more rows
#> 
#> $disp
#> # A tibble: 32 x 2
#>    key       y
#>    <chr> <dbl>
#>  1 disp   160 
#>  2 disp   160 
#>  3 disp   108 
#>  4 disp   258 
#>  5 disp   360 
#>  6 disp   225 
#>  7 disp   360 
#>  8 disp   147.
#>  9 disp   141.
#> 10 disp   168.
#> # … with 22 more rows
#> 
#> $drat
#> # A tibble: 32 x 2
#>    key       y
#>    <chr> <dbl>
#>  1 drat   3.9 
#>  2 drat   3.9 
#>  3 drat   3.85
#>  4 drat   3.08
#>  5 drat   3.15
#>  6 drat   2.76
#>  7 drat   3.21
#>  8 drat   3.69
#>  9 drat   3.92
#> 10 drat   3.92
#> # … with 22 more rows
#> 
#> $hp
#> # A tibble: 32 x 2
#>    key       y
#>    <chr> <dbl>
#>  1 hp      110
#>  2 hp      110
#>  3 hp       93
#>  4 hp      110
#>  5 hp      175
#>  6 hp      105
#>  7 hp      245
#>  8 hp       62
#>  9 hp       95
#> 10 hp      123
#> # … with 22 more rows
#> 
#> $mpg
#> # A tibble: 32 x 2
#>    key       y
#>    <chr> <dbl>
#>  1 mpg    21  
#>  2 mpg    21  
#>  3 mpg    22.8
#>  4 mpg    21.4
#>  5 mpg    18.7
#>  6 mpg    18.1
#>  7 mpg    14.3
#>  8 mpg    24.4
#>  9 mpg    22.8
#> 10 mpg    19.2
#> # … with 22 more rows
Created on 2019-09-03 by the reprex package (v0.3.0)
like image 852
elliot Avatar asked Sep 20 '25 01:09

elliot


1 Answers

There's actually a nice function in purrr called imap that seems to do just what you need. It iterates over both the elements (.x) and the names (.y) of the list:

df <- mtcars %>% 
  select(1:5)

# Split into many dataframes based on columns and create a named list
mtcars_ls <- df %>% 
  gather(key, value) %>%
  split(.$key) %>% 
  set_names(names(df))

imap(mtcars_ls, function(x,y) {
  x %>% 
    rename(!!quo_name(y) := value)
})

The !!quo_name and := are to allow the name strings to be tidy evaluated. To make that even simpler you could use the shorthand notation:

imap(mtcars_ls, ~ rename(.x, !!quo_name(.y) := value))
like image 94
Shinobi_Atobe Avatar answered Sep 22 '25 14:09

Shinobi_Atobe