How to apply functions 'unite' and 'strsplit' or similar functions to a list of dataframes

Viewed 97

I am new to R and recently started working with lists.

I have a list of dataframes where one dataframe looks something like this:

pos <- c("chr1","chr1","chr1")
end <- c("205","206","207")
cpy <- c("4,4","3,3","4,4")
df1 <- as.data.frame(cbind(pos,end,cpy))

df1

   pos end cpy
1 chr1 205 4,4
2 chr1 206 3,3
3 chr1 207 4,4

I want to do some manipulations where I combine the first two columns separated by ":" and split the third column and keep only the first element. I found an easy way to do these things using unite from the tidyr package and strsplit:

library(tidyr)
df1 <- unite(df1, pos, sep=":", c("pos","end"))
df1$cpy <- sapply(strsplit(df1$cpy,","), `[`, 1)

df1
   pos     cpy
1 chr1:205   4
2 chr1:206   3
3 chr1:207   4

Now I want to do this for all the dataframes in my list. For example, I want this

mylist
$df1
   pos end cpy
1 chr1 205 4,4
2 chr1 206 3,3
3 chr1 207 4,4

$df2
   pos end cpy
1 chr1 205 3,4
2 chr1 206 4,5
3 chr1 207 6,6

To become this

mylist
$df1
       pos cpy
1 chr1:205   4
2 chr1:206   3
3 chr1:207   4

$df2
       pos cpy
1 chr1:205   3
2 chr1:206   4
3 chr1:207   6

As I said I am new with R and even newer using lists. I am trying to use lapply with unite and strsplit but it doesn't work. Is it possible to use any kind of function in lapply(X, FUN, ...) or do I have to write my own function and how do I do this easily? Or if you can recommend me some online materials to help me learn the skills to solve this I would also really appreciate it!

1 Answers

We can use str_remove

  1. Loop over the list with map
  2. Modify the 'cpy' column by removing the , followed by one or more digits (\\d+) using str_remove in mutate
  3. Update the list by assignment to the same object (or different one if we want to keep the original as such)
library(dplyr)
library(purrr)
library(stringr)
lst1 <- map(lst1, ~ .x %>% 
        mutate(cpy = as.integer(str_remove(cpy, ",\\d+"))))

-output

lst1
$df1
   pos end cpy
1 chr1 205   4
2 chr1 206   3
3 chr1 207   4

$df2
   pos end cpy
1 chr1 205   3
2 chr1 206   4
3 chr1 207   6

data

lst1 <- list(df1 = structure(list(pos = c("chr1", "chr1", "chr1"), end = c("205", 
"206", "207"), cpy = c("4,4", "3,3", "4,4")), class = "data.frame", row.names = c(NA, 
-3L)), df2 = structure(list(pos = c("chr1", "chr1", "chr1"), 
    end = 205:207, cpy = c("3,4", "4,5", "6,6")), class = "data.frame", row.names = c("1", 
"2", "3")))
Related