Split comma- and colon- separated string in R

Viewed 63
Input$Freq                                                          
                                                                             Freq
                                        AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.
     AFR:0.1546,AMR:0.2581,EAS:0.0825,FIN:0.2270,NFE:0.0822,OTH:0.1706,ASJ:0.0729
                                        AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.
     AFR:0.1546,AMR:0.2581,EAS:0.0825,FIN:0.2270,NFE:0.0822,OTH:0.1706,ASJ:0.0729
                                        AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.
                                        AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.

Here is a column of a dataframe, which contains string separated by comma and colon. I want to extract the dot or the number right after EAS:. I want an output like this

Output
                                                                                 Freq       EAS
                                            AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.         .
         AFR:0.1546,AMR:0.2581,EAS:0.0825,FIN:0.2270,NFE:0.0822,OTH:0.1706,ASJ:0.0729    0.0825
                                            AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.         .
         AFR:0.1546,AMR:0.2581,EAS:0.0825,FIN:0.2270,NFE:0.0822,OTH:0.1706,ASJ:0.0729    0.0825
                                            AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.         .
                                            AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.         .

I've tried extract in tidyr

maf_snv_intervar <- extract(Input, Freq, into = 'EAS', 
                            "^[^,]+,[^,]+,([^,]+),.*", remove = F, convert = T)

But I got an output like this

Output
                                                                                 Freq          EAS
                                            AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.        EAS:.
         AFR:0.1546,AMR:0.2581,EAS:0.0825,FIN:0.2270,NFE:0.0822,OTH:0.1706,ASJ:0.0729   EAS:0.0825
                                            AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.        EAS:.
         AFR:0.1546,AMR:0.2581,EAS:0.0825,FIN:0.2270,NFE:0.0822,OTH:0.1706,ASJ:0.0729   EAS:0.0825
                                            AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.        EAS:.
                                            AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.        EAS:.

I dont know how to modify the regex.

1 Answers

We could change the regex with str_extract and specify a regex lookaround to match the EAS substring ((?<=EAS:)) that precedes before any characters that are not a , ([^,]+)

library(dplyr)
library(stringr)
Input <- Input %>%
    mutate(EAS = str_extract(Freq, '(?<=EAS:)[^,]+'))

-output

Input
                                                                          Freq    EAS
1                                    AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.      .
2 AFR:0.1546,AMR:0.2581,EAS:0.0825,FIN:0.2270,NFE:0.0822,OTH:0.1706,ASJ:0.0729 0.0825
3                                    AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.      .
4 AFR:0.1546,AMR:0.2581,EAS:0.0825,FIN:0.2270,NFE:0.0822,OTH:0.1706,ASJ:0.0729 0.0825
5                                    AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.      .
6                                    AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.      .

In the OP's code with extract, replace the regex with

library(tidyr)
Input %>% 
    extract(Freq, into = 'EAS', "^[^,]+,[^,]+,EAS:([^,]+),.*", remove = FALSE)
                                                                          Freq    EAS
1                                    AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.      .
2 AFR:0.1546,AMR:0.2581,EAS:0.0825,FIN:0.2270,NFE:0.0822,OTH:0.1706,ASJ:0.0729 0.0825
3                                    AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.      .
4 AFR:0.1546,AMR:0.2581,EAS:0.0825,FIN:0.2270,NFE:0.0822,OTH:0.1706,ASJ:0.0729 0.0825
5                                    AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.      .
6                                    AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.      .

data

Input <- structure(list(Freq = c("AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.", 
"AFR:0.1546,AMR:0.2581,EAS:0.0825,FIN:0.2270,NFE:0.0822,OTH:0.1706,ASJ:0.0729", 
"AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.", "AFR:0.1546,AMR:0.2581,EAS:0.0825,FIN:0.2270,NFE:0.0822,OTH:0.1706,ASJ:0.0729", 
"AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:.", "AFR:.,AMR:.,EAS:.,FIN:.,NFE:.,OTH:.,ASJ:."
)), class = "data.frame", row.names = c(NA, -6L))
Related