James
James

Reputation: 51

Select unique values

I need to change this function that doesn't match for unique values. For example, if I want MAPK4, the function matches MAPK41 and AMAPK4 etc. The function must select only the unique values.

Function:

library(dplyr)

df2 <- df %>% 
  rowwise() %>%
  mutate(mutated = paste(mutated_genes[unlist(
    lapply(mutated_genes, function(x) grepl(x,genes, ignore.case = T)))], collapse=","),
    circuit_name = gsub("", "", circuit_name)) %>%
  select(-genes) %>%
  data.frame()

data:

df <-structure(list(circuit_name = c("hsa04010__117", "hsa04014__118" ), genes = c("MAP4K4,DUSP10*,DUSP10*,DUSP10*,DUSP10*,DUSP10*,DUSP10*,DUSP10*,DUSP10*,DUSP10*,DUSP10*,DUSP3*,DUSP3*,DUSP3*,DUSP3*,PPM1A,AKT3,AKT3,AKT3,ZAK,MAP3K12,MAP3K13,TRAF2,CASP3,IL1R1,IL1R1,TNFRSF1A,IL1A,IL1A,TNF,RAC1,RAC1,RAC1,RAC1,MAP2K7,MAPK8,MAPK8,MAPK8,MECOM,HSPA1A,HSPA1A,HSPA1A,HSPA1A,HSPA1A,HSPA1A,MAP4K3,MAPK8IP2,MAP4K1",  "MAP4K4,DUSP10*,DUSP10*,DUSP10*,DUSP10*,DUSP10*")), class = "data.frame", row.names = c(NA,  -2L))  
mutated_genes <- c("MAP4K4", "MAP3K12","TRAF2", "CACNG3")

output:

  circuit_name      mutated
1  hsa04010__117 MAP4K4,TRAF2
2  hsa04014__118       MAP4K4

Upvotes: 0

Views: 62

Answers (3)

akrun
akrun

Reputation: 886938

We can use str_extract

library(stringr)
df$mutated <- sapply(str_extract_all(df$genes, paste(mutated_genes, 
         collapse="|")), toString)

Upvotes: 0

Maurits Evers
Maurits Evers

Reputation: 50668

Please note that based on the mutated_genes vector, your expected output is missing MAP3K12 for hsa04010__117.

Here is a tidyverse possibility

df %>%
    separate_rows(genes) %>%
    filter(genes %in% mutated_genes) %>%
    group_by(circuit_name) %>%
    summarise(mutated = toString(genes))
## A tibble: 2 x 2
#  circuit_name  mutated
#  <chr>         <chr>
#1 hsa04010__117 MAP4K4, MAP3K12, TRAF2
#2 hsa04014__118 MAP4K4

Explanation: We separate comma-separated entries into different rows, then select only those rows where genes %in% mutated_genes and summarise results per circuit_name by concatenating genes entries.


PS. Personally I'd recommend keeping the data in a tidy long format (i.e. don't concatenate entries with toString); that way you have one row per gene, which will make any post-processing of the data much more straightforward.

Upvotes: 1

Ronak Shah
Ronak Shah

Reputation: 388797

A base R approach would be by splitting the genes on "," and return those string which match mutated_genes.

df$mutated <- sapply(strsplit(df$genes, ","), function(x) 
   toString(grep(paste0(mutated_genes, collapse = "|"), x, value = TRUE)))

df[c(1, 3)]
#   circuit_name                mutated
#1 hsa04010__117 MAP4K4, MAP3K12, TRAF2
#2 hsa04014__118                 MAP4K4

Upvotes: 1

Related Questions