Search code examples
rdataframedplyrsubset

Subsetting columns from a dataframe to create new dataframes by iteration


I have a large dataframe and want to create several new dataframes from individual columns. Each new dataframe should consist of the first two columns plus one of the next columns.

I can do this manually; my desired dummy products being subA, subB, and subC.

library(tidyverse)

# dummy dataframe
chr1 <- letters[1:4]
chr2 <- letters[23:26]
A <- 1:4
B <- 5:8
C <- 9:12
data <- tibble(chr1, chr2, A, B, C)

# manual subsetting
subA <- data %>%
  select(chr1, chr2, A)

subB <- data %>%
  select(chr1, chr2, B)

subC <- data %>%
  select(chr1, chr2, C)

However, my original dataframe has about 700 columns, so I am looking for some kind of simple iteration, preferably in tidyverse (purrr), that is flexible enough to be supplemented by pipes into additional functions.


Solution

  • in base:

    lapply(split.default(data[-c(1,2)], names(data[-c(1,2)])), function(x) 
            cbind(data[c(1,2)], x))
    

    or in tidyverse:

    data %>% 
      pivot_longer(-c(1, 2)) %>% 
      split(., .$name) %>% 
      map(., ~pivot_wider(.x))
    
    #> $A
    #> # A tibble: 4 x 3
    #>   chr1  chr2      A
    #>   <chr> <chr> <int>
    #> 1 a     w         1
    #> 2 b     x         2
    #> 3 c     y         3
    #> 4 d     z         4
    #> 
    #> $B
    #> # A tibble: 4 x 3
    #>   chr1  chr2      B
    #>   <chr> <chr> <int>
    #> 1 a     w         5
    #> 2 b     x         6
    #> 3 c     y         7
    #> 4 d     z         8
    #> 
    #> $C
    #> # A tibble: 4 x 3
    #>   chr1  chr2      C
    #>   <chr> <chr> <int>
    #> 1 a     w         9
    #> 2 b     x        10
    #> 3 c     y        11
    #> 4 d     z        12
    

    If you want to save these as individual dataframes:

    list2env(
        lapply(split.default(data[-c(1,2)], paste0("sub", names(data[-c(1,2)]))), function(x) 
               cbind(data[c(1,2)], x)),  
        envir=.GlobalEnv)
    

    Created on 2024-01-16 with reprex v2.0.2