Transforming data in R for multiple samples

Viewed 54

I have a large list of data frames containing multiple samples, such as the example code shown below.

I've managed to subset them by type (protein or mRNA), but now I would like to transform the data into a table with sample_ID as the first column (with a row for each sample) and the names of proteins/mRNA along the top (as samples have expression values for a few of the same proteins/mRNA), and then the values for expression for the protein/mRNA in the rows for each sample.

Any help would be appreciated, thanks!!

#Example data
sample_8765 <- data.frame(type = c("protein", "mRNA", "mRNA", "mRNA", "protein"),
                      name = c("DIABLO", "X1345", "X1234", "F1234", "p53"),
                      expression = c("1.23", "4.265", "3.44", "6.43", "8.00"))

sample_8901 <- data.frame(type = c("protein", "mRNA", "protein","mRNA", "protein"),
                      name = c("DIABLO", "X1345", "SMAC", "F4657", "MDM2"),
                      expression = c("3.24", "5.33", "4.35", "6.78", "9.11"))

sample_9084 <- data.frame(type = c("protein", "protein", "mRNA", "mRNA", "mRNA"),
                      name = c("SMAC", "DIABLO", "X1345", "F4657", "X1234" ),
                      expression = c("2.56", "8.11", "4.35", "6.78", "9.11"))
sample_ID <- c("sample_8765","sample_8901","sample3_9084")

#subseting by type 
library(dplyr)
bind_rows(mget(paste0(sample_ID))) %>%
  split(.$type) %>%
  list2env(.GlobalEnv)

mRNA 
#type  name expression
#2  mRNA X1345      4.265
#3  mRNA X1234       3.44
#4  mRNA F1234       6.43
#7  mRNA X1345       5.33
#9  mRNA F4657       6.78
#13 mRNA X1345       4.35
#14 mRNA F4657       6.78
#15 mRNA X1234       9.11

The output that I would like to see is something like this:

protein

sample_ID   DIABLO SMAC  X1345  F4657  X1234
sample_8765 1.23.  NA    4.265. 9.11.  3.44
sample_8901 3.24.  4.35  4.265. NA.    NA
sample_9084 8.11.  2.56  4.35.  6.78.  9.11
2 Answers

bind_rows has an argument called .id that allows the users to specify a column name which will show the name of the data frame in the list, so by slight modification of your code we can achieve what you described.

library(dplyr)
bind_rows(mget(paste0(sample_ID)), .id = "Sample_ID") %>%
  pivot_wider(names_from = "name", values_from = "expression") %>%
  split(.$type) %>%
  list2env(.GlobalEnv)

Is this required?

purrr::imap_dfr(mget(paste0(sample_ID)), ~ .x %>% mutate(sample_id = .y)) %>%
  pivot_wider(id_cols = sample_id, values_from = expression, names_from = name)

# A tibble: 3 x 9
  sample_id   DIABLO X1345 X1234 F1234 p53   SMAC  F4657 MDM2 
  <chr>       <chr>  <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 sample_8765 1.23   4.265 3.44  6.43  8.00  NA    NA    NA   
2 sample_8901 3.24   5.33  NA    NA    NA    4.35  6.78  9.11 
3 sample_9084 8.11   4.35  9.11  NA    NA    2.56  6.78  NA
Related