Possible duplicate Here
I have a data frame of two columns. I want to remove the string in parenthesis and add that as a new column. Data frame is displayed below.
structure(list(ID = 1:12, Gene.Name = structure(c(3L, 11L, 9L,
5L, 1L, 8L, 2L, 4L, 6L, 12L, 10L, 7L), .Label = c(" ATP synt, H+ tran, O subunit (oligomycin sensitivity conferring protein) (ATP5O), mRNA",
" heterogeneous nuclear ribonucleoprotein F (HNRPF), mRNA", " NADH (ubiquinone) 1 alpha subcomplex, 4 (9kD, MLRQ) (NDUFA4), mRNA",
" ribosomal protein L34 (RPL34), transcript variant 1, mRNA",
" ribosomal protein S11 (RPS11), mRNA", "ATP synthase, H+ tran, mitochondrial F0, subunit c (subunit 9) isoform 3 (ATP5G3), mRNA",
"clone MGC:10120 IMAGE:3900723, mRNA, complete cds", "cytidine monophosphate N-acetylneuraminic acid synthetase (CMAS), mRNA",
"farnesyl-diphosphate farnesyltransferase 1 (FDFT1), mRNA", "homeobox protein from AL590526 (LOC84528), mRNA",
"mitochondrial S33 (MRPS33), transcript variant 1, nuclear gene, mRNA",
"ribosomal protein S15a (RPS15A), mRNA"), class = "factor")), .Names = c("ID",
"Gene.Name"), row.names = c(NA, -12L), class = "data.frame")
if the string in parenthesis is not found, then leave that row empty. Here i have two cases
1) Get all the string in parenthesis and add as a new column separated by ,
2) Last string in parenthesis and add as new column
I tried something like df$Symbol <- sapply(df, function(x) sub("\\).*", "", sub(".*\\(", "", x))) but does not give the appropriate output
Case 1 output
ID Gene.Name Symbol
1 NADH (ubiquinone) 1 alpha subcomplex, 4 (9kD, MLRQ) (NDUFA4), mRNA ubiquinone, (9kD, MLRQ),NDUFA4
2 mitochondrial S33 (MRPS33), transcript variant 1, nuclear gene, mRNA MRPS33
3 farnesyl-diphosphate farnesyltransferase 1 (FDFT1), mRNA FDFT1
4 ribosomal protein S11 (RPS11), mRNA RPS11
5 ATP synt, H+ tran, O subunit (oligomycin sensitivity conferring protein) (ATP5O), mRNA oligomycin sensitivity conferring protein,ATP5O
6 cytidine monophosphate N-acetylneuraminic acid synthetase (CMAS), mRNA CMAS
7 heterogeneous nuclear ribonucleoprotein F (HNRPF), mRNA HNRPF
8 ribosomal protein L34 (RPL34), transcript variant 1, mRNA RPL34
9 ATP synthase, H+ tran, mitochondrial F0, subunit c (subunit 9) isoform 3 (ATP5G3), mRNA subunit 9,ATP5G3
10 ribosomal protein S15a (RPS15A), mRNA RPS15A
11 homeobox protein from AL590526 (LOC84528), mRNA LOC84528
12 clone MGC:10120 IMAGE:3900723, mRNA, complete cds NA
Case 2 output
ID Gene.Name Symbol
1 NADH (ubiquinone) 1 alpha subcomplex, 4 (9kD, MLRQ) (NDUFA4), mRNA NDUFA4
2 mitochondrial S33 (MRPS33), transcript variant 1, nuclear gene, mRNA MRPS33
3 farnesyl-diphosphate farnesyltransferase 1 (FDFT1), mRNA FDFT1
4 ribosomal protein S11 (RPS11), mRNA RPS11
5 ATP synt, H+ tran, O subunit (oligomycin sensitivity conferring protein) (ATP5O), mRNA ATP5O
6 cytidine monophosphate N-acetylneuraminic acid synthetase (CMAS), mRNA CMAS
7 heterogeneous nuclear ribonucleoprotein F (HNRPF), mRNA HNRPF
8 ribosomal protein L34 (RPL34), transcript variant 1, mRNA RPL34
9 ATP synthase, H+ tran, mitochondrial F0, subunit c (subunit 9) isoform 3 (ATP5G3), mRNA ATP5G3
10 ribosomal protein S15a (RPS15A), mRNA RPS15A
11 homeobox protein from AL590526 (LOC84528), mRNA LOC84528
12 clone MGC:10120 IMAGE:3900723, mRNA, complete cds <NA>
An option using sub to get the words inside the round brackets at the end of the string.
Symbol <- sub('.*\\(([^\\)]+)\\)[^\\(]+$', '\\1',df1[,2])
df1$Symbol <- Symbol[1:nrow(df1)*NA^(!grepl('\\(',df1[,2]))]
df1$Symbol
#[1] "NDUFA4" "MRPS33" "FDFT1" "RPS11" "ATP5O" "CMAS"
#[7] "HNRPF" "RPL34" "ATP5G3" "RPS15A" "LOC84528" NA
Update
For the first case, ie. extract all characters within the round brackets and paste them together using ,, one option is rm_round from qdapRegex. The output of rm_round is a list. So we use lapply/sapply to loop through the list. Strings that have , inside are separated with grep and we paste the round brackets, and then paste the strings together with collapse=', '. A convenient wrapper function is toString.
library(qdapRegex)
df1$allSymbol <- sapply(rm_round(df1[,2],extract=TRUE), function(x) {
indx <- grep(',', x)
x[indx] <-paste0("(", x[indx], ")")
toString(x)})
is.na(df1$allSymbol) <- df1$allSymbol=='NA'
df1[3:4]
# allSymbol Symbol
#1 ubiquinone, (9kD, MLRQ), NDUFA4 NDUFA4
#2 MRPS33 MRPS33
#3 FDFT1 FDFT1
#4 RPS11 RPS11
#5 oligomycin sensitivity conferring protein, ATP5O ATP5O
#6 CMAS CMAS
#7 HNRPF HNRPF
#8 RPL34 RPL34
#9 subunit 9, ATP5G3 ATP5G3
#10 RPS15A RPS15A
#11 LOC84528 LOC84528
#12 <NA> <NA>
I think I took the easy way out, but if you can get away with it, only match the things in the parentheses that look like a gene symbol, ie, only capital letters and digits
dd <- structure(list(ID = 1:12, Gene.Name = structure(c(3L, 11L, 9L, 5L, 1L, 8L, 2L, 4L, 6L, 12L, 10L, 7L), .Label = c(" ATP synt, H+ tran, O subunit (oligomycin sensitivity conferring protein) (ATP5O), mRNA", " heterogeneous nuclear ribonucleoprotein F (HNRPF), mRNA", " NADH (ubiquinone) 1 alpha subcomplex, 4 (9kD, MLRQ) (NDUFA4), mRNA", " ribosomal protein L34 (RPL34), transcript variant 1, mRNA", " ribosomal protein S11 (RPS11), mRNA", "ATP synthase, H+ tran, mitochondrial F0, subunit c (subunit 9) isoform 3 (ATP5G3), mRNA", "clone MGC:10120 IMAGE:3900723, mRNA, complete cds", "cytidine monophosphate N-acetylneuraminic acid synthetase (CMAS), mRNA", "farnesyl-diphosphate farnesyltransferase 1 (FDFT1), mRNA", "homeobox protein from AL590526 (LOC84528), mRNA", "mitochondrial S33 (MRPS33), transcript variant 1, nuclear gene, mRNA", "ribosomal protein S15a (RPS15A), mRNA"), class = "factor")), .Names = c("ID", "Gene.Name"), row.names = c(NA, -12L), class = "data.frame")
dd$Gene.Name <- as.character(dd$Gene.Name)
## case 1
mm <- gregexpr('(?<=\\()(.*?)(?=\\))', dd$Gene.Name, perl = TRUE)
mm <- regmatches(dd$Gene.Name, mm)
dd <- cbind(dd, case1 = sapply(mm, function(x)
ifelse(length(x), paste(x, collapse = ', '), NA)))
dd[, c(1,3)]
# ID case1
# 1 1 ubiquinone, 9kD, MLRQ, NDUFA4
# 2 2 MRPS33
# 3 3 FDFT1
# 4 4 RPS11
# 5 5 oligomycin sensitivity conferring protein, ATP5O
# 6 6 CMAS
# 7 7 HNRPF
# 8 8 RPL34
# 9 9 subunit 9, ATP5G3
# 10 10 RPS15A
# 11 11 LOC84528
# 12 12 <NA>
## case 2
mm <- gregexpr('(?<=\\()([A-Z0-9]+)(?=\\))', dd$Gene.Name, perl = TRUE)
mm <- regmatches(dd$Gene.Name, mm)
dd <- cbind(dd, case2 = sapply(mm, function(x) ifelse(length(x), x, NA)))
dd[, c(1,4)]
# ID case2
# 1 1 NDUFA4
# 2 2 MRPS33
# 3 3 FDFT1
# 4 4 RPS11
# 5 5 ATP5O
# 6 6 CMAS
# 7 7 HNRPF
# 8 8 RPL34
# 9 9 ATP5G3
# 10 10 RPS15A
# 11 11 LOC84528
# 12 12 <NA>
Related
This is a rather tricky question indeed. It would be awesome if someone might be able to help me out.
What I'm trying to do is the following. I have data frame in R containing every locality in a given state, scraped from Wikipedia. It looks something like this (top 10 rows). Let's call it NewHampshire.df:
Municipality County Population
1 Acworth Sullivan 891
2 Albany Carroll 735
3 Alexandria Grafton 1613
4 Allenstown Merrimack 4322
5 Alstead Cheshire 1937
6 Alton Belknap 5250
7 Amherst Hillsborough 11201
8 Andover Merrimack 2371
9 Antrim Hillsborough 2637
10 Ashland Grafton 2076
I've further compiled a new variable called grep_term, which combines the values from Municipality and County into a new, variable that functions as an or-statement, something like this:
Municipality County Population grep_term
1 Acworth Sullivan 891 "Acworth|Sullivan"
2 Albany Carroll 735 "Albany|Carroll"
and so on. Furthermore, I have another dataset, containing self-disclosed locations of 2000 Twitter users. I call it location.df, and it looks a bit like this:
[1] "London" "Orleans village VT USA" "The World"
[4] "D M V Towson " "Playa del Sol Solidaridad" "Beautiful Downtown Burbank"
[7] NA "US" "Gaithersburg Md"
[10] NA "California " "Indy"
[13] "Florida" "exsnaveen com" "Houston TX"
I want to do two things:
1: Grepl through every observation in the location.df dataset, and save a TRUE or FALSE into a new variable depending on whether the self-disclosed location is part of the list in the first dataset.
2: Save the number of matches for a particular line in the NewHampshire.df dataset to a new variable. I.e., if there are 4 matches for Acworth in the twitter location dataset, there should be a value "4" for observation 1 in the NewHampshire.df on the newly created "matches" variable
What I've done so far: I've solved task 1, as follows:
for(i in 1:234){
location.df$isRelevant <- sapply(location.df$location, function(s) grepl(NH_Places[i], s, ignore.case = TRUE))
}
How can I solve task 2, ideally in the same for loop?
Thanks in advance, any help would be greatly appreciated!
With regard to task one, you could also use:
# location vector to be matched against
loc.vec <- c("Acworth","Hillsborough","California","Amherst","Grafton","Ashland","London")
location.df <- data.frame(location=loc.vec)
# create a 'grep-vector'
places <- paste(paste(NewHampshire$Municipality, NewHampshire$County,
sep = "|"),
collapse = "|")
# match them against the available locations
location.df$isRelevant <- sapply(location.df$location,
function(s) grepl(places, s, ignore.case = TRUE))
which gives:
> location.df
location isRelevant
1 Acworth TRUE
2 Hillsborough TRUE
3 California FALSE
4 Amherst TRUE
5 Grafton TRUE
6 Ashland TRUE
7 London FALSE
To get the number of matches in the location.df with the grep_term column, you can use:
NewHampshire$n.matches <- sapply(NewHampshire$grep_term, function(x) sum(grepl(x, loc.vec)))
gives:
> NewHampshire
Municipality County Population grep_term n.matches
1 Acworth Sullivan 891 Acworth|Sullivan 1
2 Albany Carroll 735 Albany|Carroll 0
3 Alexandria Grafton 1613 Alexandria|Grafton 1
4 Allenstown Merrimack 4322 Allenstown|Merrimack 0
5 Alstead Cheshire 1937 Alstead|Cheshire 0
6 Alton Belknap 5250 Alton|Belknap 0
7 Amherst Hillsborough 11201 Amherst|Hillsborough 2
8 Andover Merrimack 2371 Andover|Merrimack 0
9 Antrim Hillsborough 2637 Antrim|Hillsborough 1
10 Ashland Grafton 2076 Ashland|Grafton 2
I have some string data as follows in R.
DT <- structure(list(ID = c(1, 2, 3, 4, 5, 6), GKT = c("G1:GRST, G45:KRPT",
"G48932:KD56", "G7764:MGI45, K7786:IRE4R, K45:TG45", "K4512:3345, G51:56:34, K22:45I67",
"K678:RT,IG, G123:TGIF, G33:IG56", "T4534:K456")), .Names = c("ID",
"GKT"), class = "data.frame", row.names = c(NA, 6L))
DT
ID GKT
1 1 G1:GRST, G45:KRPT
2 2 G48932:KD56
3 3 G7764:MGI45, K7786:IRE4R, K45:TG45
4 4 K4512:3345, G51:56:34, K22:45I67
5 5 K678:RT,IG, G123:TGIF, G33:IG56
6 6 T4534:K456
I want to get the output out from DT$GKT using gsub and regex in R.
out <- c("G1, G45", "G48932", "G7764, K7786, K45", "K4512, G51, K22",
"K678, G123, G33", "T4534")
DT$out <- out
DT
ID GKT out
1 1 G1:GRST, G45:KRPT G1, G45
2 2 G48932:KD56 G48932
3 3 G7764:MGI45, K7786:IRE4R, K45:TG45 G7764, K7786, K45
4 4 K4512:3345, G51:56:34, K22:45I67 K4512, G51, K22
5 5 K678:RT,IG, G123:TGIF, G33:IG56 K678, G123, G33
6 6 T4534:K456 T4534
I have tried gsub(x=DT$GKT, pattern = "(:)(.*)(, |\\b)", replacement=""), but it fetches only first instances.
gsub(x=DT$GKT, pattern = "(:)(.*)(, |\\b)", replacement="")
[1] "G1" "G48932" "G7764" "K4512" "K678" "T4534"
Another option using gsub is to use a look behind
DT$out <- gsub("(?=:)(.[A-Z0-9,]+)(?=\\b)", "", DT$GKT, perl = TRUE)
DT
# ID GKT out
# 1 1 G1:GRST, G45:KRPT G1, G45
# 2 2 G48932:KD56 G48932
# 3 3 G7764:MGI45, K7786:IRE4R, K45:TG45 G7764, K7786, K45
# 4 4 K4512:3345, G51:56:34, K22:45I67 K4512, G51, K22
# 5 5 K678:RT,IG, G123:TGIF, G33:IG56 K678, G123, G33
# 6 6 T4534:K456 T4534
EDIT
You can use the following regular expression for replacing ...
DT$out <- gsub(':\\S+\\b', '', DT$GKT)
DT
# ID GKT out
# 1 1 G1:GRST, G45:KRPT G1, G45
# 2 2 G48932:KD56 G48932
# 3 3 G7764:MGI45, K7786:IRE4R, K45:TG45 G7764, K7786, K45
# 4 4 K4512:3345, G51:56:34, K22:45I67 K4512, G51, K22
# 5 5 K678:RT,IG, G123:TGIF, G33:IG56 K678, G123, G33
# 6 6 T4534:K456 T4534
You could use a lookahead (?=) to check for : and capture just the first group
unlist(regmatches(DT$GKT, gregexpr("([A-Z0-9]+)(?=:)", DT$GKT, perl=T)))
# [1] "G1" "G45" "G48932" "G7764" "K7786" "K45" "K4512" "G51"
# [9] "56" "K22" "K678" "G123" "G33" "T4534"
I have a data.table similar to the one as follows
Data
library(data.table)
DT <- structure(list(N = 1:6, VN = c("v1", "v3", "v6", "v7a", "v18",
"v23"), T1 = c("bigby (wolf)", "white", "red (rose)", "piggy (straw)",
"(curse) beast", "prince"), T2 = c("jack (bean)", "snow (dwarves)",
"beard (blue)", "bhageera (jungle) mowgli (book)", "beauty",
"glass (slipper)"), T3 = c("hk (34)", "VL (r45)", "tg (h5)",
"tt (HG) (45)", "gh", "vlp"), Val = c(36, 25, 0.84, 12, 78, 258
)), .Names = c("N", "VN", "T1", "T2", "T3", "Val"), class = "data.frame", row.names = c(NA,
-6L))
setDT(DT)
DT
N VN T1 T2 T3 Val
1: 1 v1 bigby (wolf) jack (bean) hk (34) 36.00
2: 2 v3 white snow (dwarves) VL (r45) 25.00
3: 3 v6 red (rose) beard (blue) tg (h5) 0.84
4: 4 v7a piggy (straw) bhageera (jungle) mowgli (book) tt (HG) (45) 12.00
5: 5 v18 (curse) beast beauty gh 78.00
6: 6 v23 prince glass (slipper) vlp 258.00
I want to extract all the strings within parentheses from columns T1 and T2 to a new column C.
I can do it to single rows as follows.
Rowwise calculations
setDF(DT)
dtf <- c("T1", "T2")
paste(unique(unlist(regmatches(DT[4,dtf], gregexpr("(?=\\().*?(?<=\\))", DT[4,dtf], perl=T)))), collapse=" ")
[1] "(straw) (jungle) (book)"
paste(unique(unlist(regmatches(DT[3,dtf], gregexpr("(?=\\().*?(?<=\\))", DT[3,dtf], perl=T)))), collapse=" ")
[1] "(rose) (blue)"
I am not able to get similar results using data.table.
Try with data.table
setDT(DT)
DT[, C := paste(unique(unlist(regmatches(get(dtf), gregexpr("(?=\\().*?(?<=\\))", get(dtf), perl=T)))), collapse=" ")]
How to use data.table to get the desired result?
Desired result
out <- structure(list(N = 1:6, VN = c("v1", "v3", "v6", "v7a", "v18",
"v23"), T1 = c("bigby (wolf)", "white", "red (rose)", "piggy (straw)",
"(curse) beast", "prince"), T2 = c("jack (bean)", "snow (dwarves)",
"beard (blue)", "bhageera (jungle) mowgli (book)", "beauty",
"glass (slipper)"), T3 = c("hk (34)", "VL (r45)", "tg (h5)",
"tt (HG) (45)", "gh", "vlp"), Val = c(36, 25, 0.84, 12, 78, 258
), C = c("(wolf) (bean)", "(dwarves)", "(rose) (blue)", "(straw) (jungle) (book)",
"(curse)", "(slipper)")), .Names = c("N", "VN", "T1", "T2", "T3",
"Val", "C"), class = "data.frame", row.names = c(NA, -6L))
out
N VN T1 T2 T3 Val C
1 1 v1 bigby (wolf) jack (bean) hk (34) 36.00 (wolf) (bean)
2 2 v3 white snow (dwarves) VL (r45) 25.00 (dwarves)
3 3 v6 red (rose) beard (blue) tg (h5) 0.84 (rose) (blue)
4 4 v7a piggy (straw) bhageera (jungle) mowgli (book) tt (HG) (45) 12.00 (straw) (jungle) (book)
5 5 v18 (curse) beast beauty gh 78.00 (curse)
6 6 v23 prince glass (slipper) vlp 258.00 (slipper)
You can use by and .SDcols to do this.
setDT(DT)
dtf <- c("T1", "T2")
DT[, C := paste(unique(unlist(regmatches(.SD, gregexpr("(?=\\().*?(?<=\\))", .SD, perl=T)))),
collapse=" "),
by = N,
.SDcols = dtf]
DT
## N VN T1 T2 T3 Val C
## 1: 1 v1 bigby (wolf) jack (bean) hk (34) 36.00 (wolf) (bean)
## 2: 2 v3 white snow (dwarves) VL (r45) 25.00 (dwarves)
## 3: 3 v6 red (rose) beard (blue) tg (h5) 0.84 (rose) (blue)
## 4: 4 v7a piggy (straw) bhageera (jungle) mowgli (book) tt (HG) (45) 12.00 (straw) (jungle) (book)
## 5: 5 v18 (curse) beast beauty gh 78.00 (curse)
## 6: 6 v23 prince glass (slipper) vlp 258.00 (slipper)
I have a column as follows in a dataframe called PeakBoundaries:
chrom
chr11:69464719-69502928
chr7:55075808-55093954
chr8:128739772-128762863
chr3:169389459-169490555
chr17:37848534-37877201
chr19:30306758-30316875
chr1:150496857-150678056
chr12:69183279-69260755
chr11:77610143-77641464
chr8:38191804-38260814
chr12:58135797-58156509
I would like to separate out the columns so that the columns look like below in a dataframe:
chr chrStart chrEnd
chr11 69464719 69502928
chr7 55075808 55093954
chr8 128739772 128762863
chr3 169389459 169490555
etc.
I have tried a regular expression approach but am not getting anywhere in terms of getting the match to enter into a new column:
PeakBoundaries$chrOnly <- PeakBoundaries[grep("\\w+?=\\:"),PeakBoundaries$chrom]
I am met with the error:
Error in [.data.frame(PeakBoundaries, grep("\w+?=\:"), PeakBoundaries$chrom) :
undefined columns selected
Try this - no regex needed, just the strsplit function:
dat <- read.table(text="chr11:69464719-69502928
chr7:55075808-55093954
chr8:128739772-128762863
chr3:169389459-169490555
chr17:37848534-37877201
chr19:30306758-30316875
chr1:150496857-150678056
chr12:69183279-69260755
chr11:77610143-77641464
chr8:38191804-38260814
chr12:58135797-58156509", stringsAsFactors=FALSE)
dat[,2:4] <- matrix(unlist(strsplit(dat[,1],split = "\\:|\\-")), ncol=3, byrow=TRUE)
colnames(dat) <- c("chrom", "chr", "chrStart", "chrEnd")
# Convert last two columns from character to numeric:
dat$chrStart <- as.numeric(dat$chrStart)
dat$chrEnd <- as.numeric(dat$chrEnd)
Results
> res
chrom chr chrStart chrEnd
1 chr11:69464719-69502928 chr11 69464719 69502928
2 chr7:55075808-55093954 chr7 55075808 55093954
3 chr8:128739772-128762863 chr8 128739772 128762863
4 chr3:169389459-169490555 chr3 169389459 169490555
5 chr17:37848534-37877201 chr17 37848534 37877201
6 chr19:30306758-30316875 chr19 30306758 30316875
7 chr1:150496857-150678056 chr1 150496857 150678056
8 chr12:69183279-69260755 chr12 69183279 69260755
9 chr11:77610143-77641464 chr11 77610143 77641464
10 chr8:38191804-38260814 chr8 38191804 38260814
11 chr12:58135797-58156509 chr12 58135797 58156509
Edit
You could do everything using only your existing dataframe. Replace dat[,1] with PeakBoundaries$chrom and dat[,2:4] with PeakBoundaries[,(ncol(PeakBoundaries)+1):(ncol(PeakBoundaries)+3)] and you should have it!
Edit By OP
OK so I think there's something a bit odd with my dataset but I've sorted it with Dominic's help so that it it is now:
PeakBoundaries <- as.data.frame(PeakBoundaries)
PeakBoundaries <- PeakBoundaries[-1,]
PeakBoundaries <- as.data.frame(PeakBoundaries)
PeakBoundaries$PeakBoundaries <-
as.character(PeakBoundaries$PeakBoundaries)
PeakBoundaries[,(ncol(PeakBoundaries)+1):(ncol(PeakBoundaries)+3)] <-
matrix(unlist(strsplit(PeakBoundaries$PeakBoundaries,
split = "\\:|\\-")), ncol=3, byrow=TRUE)
A shorter version of Dominic's answer, making the insertion a one-liner:
dat <- data.frame(chrom = readLines(textConnection("chr11:69464719-69502928
chr7:55075808-55093954
chr8:128739772-128762863
chr3:169389459-169490555
chr17:37848534-37877201
chr19:30306758-30316875
chr1:150496857-150678056
chr12:69183279-69260755
chr11:77610143-77641464
chr8:38191804-38260814
chr12:58135797-58156509")) )
dat[, c('chr','chrStart','chrEnd')] <- t( sapply( dat$chrom, function(s) { str_split(s, '[:-]') [[1]] } ) )
dat$chrStart <- as.numeric(dat$chrStart)
dat$chrEnd <- as.numeric(dat$chrEnd)
We could try
library(tidyr)
extract(dat, chrom, into=c('chr', 'chrStart', 'chrEnd'),
'([^:]+):([^-]+)-(.*)', convert=TRUE)
# chr chrStart chrEnd
#1 chr11 69464719 69502928
#2 chr7 55075808 55093954
#3 chr8 128739772 128762863
#4 chr3 169389459 169490555
#5 chr17 37848534 37877201
#6 chr19 30306758 30316875
#7 chr1 150496857 150678056
#8 chr12 69183279 69260755
#9 chr11 77610143 77641464
#10 chr8 38191804 38260814
#11 chr12 58135797 58156509
Or a faster option using the devel version of data.table. We can install the v1.9.5 from here
library(data.table) # v1.9.5+
nm1 <- c('chr', 'chrStart', 'chrEnd')
res <- setDT(tstrsplit(dat$chrom, '[:-]', type.convert=TRUE))
setnames(res, nm1)
res
# chr chrStart chrEnd
# 1: chr11 69464719 69502928
# 2: chr7 55075808 55093954
# 3: chr8 128739772 128762863
# 4: chr3 169389459 169490555
# 5: chr17 37848534 37877201
# 6: chr19 30306758 30316875
# 7: chr1 150496857 150678056
# 8: chr12 69183279 69260755
# 9: chr11 77610143 77641464
#10: chr8 38191804 38260814
#11: chr12 58135797 58156509
Or
library(splitstackshape)
setnames(cSplit(dat, 'chrom', ':|-',fixed=FALSE,
type.convert=TRUE), nm1)[]
data
dat <- structure(list(chrom = structure(c(2L, 9L, 10L, 8L, 6L, 7L, 1L,
5L, 3L, 11L, 4L), .Label = c("chr1:150496857-150678056",
"chr11:69464719-69502928",
"chr11:77610143-77641464", "chr12:58135797-58156509",
"chr12:69183279-69260755",
"chr17:37848534-37877201", "chr19:30306758-30316875",
"chr3:169389459-169490555",
"chr7:55075808-55093954", "chr8:128739772-128762863",
"chr8:38191804-38260814"
), class = "factor")), .Names = "chrom", row.names = c(NA, -11L
), class = "data.frame")
I am working on a data frame (df) which looks like this and can contain more than 10000 rows for some cases.
Object Coding Fn Remaining
1 T00055 T 00055_005_<002_+ 2 30
2 T00055 T 00055_008_<002_+ 2 30
3 E00336 E 00336_041_<001_+001_+ 3 0
4 E00336 E 00336_041_<001_+001_+001_+ 4 10
5 E00336 E 00336_041_<001_+001_+002_+ 4 56
6 E00336 E 00336_041_<001_+001_+002_< 4 52
7 T 00054 T 00054_013_<003_<015_+003_<001_< 4 52
I need to grep all rows which contain at least twice _+ in the string of the column Coding in order to get a data frame test.
I am trying :
test<-filter(df,
grepl("_[+].{2,}",Coding))
which cannot exclude the last row. Any idea why? Many thanks
here is the results:
Object Coding Fn Remaining
1 E00336 E 00336_041_<001_+001_+ 3 0
2 E00336 E 00336_041_<001_+001_+001_+ 4 10
3 E00336 E 00336_041_<001_+001_+002_+ 4 56
4 E00336 E 00336_041_<001_+001_+002_< 4 52
5 T 00054 T 00054_013_<003_<015_+003_<001_< 4 52
You can use this command:
subset(df, grepl("(_\\+.*){2,}", Coding))
or, with dplyr,
filter(df, grepl("(_\\+.*){2,}", Coding))
Your current regex, "_[+].{2,}", matches _+ followed by at least two characters. You need to create a group using parentheses in order to correctly apply the quantifier.
Using rex may make this type of task a little simpler.
df <- structure(list(Object = c("T00055", "T00055", "E00336", "E00336",
"E00336", "E00336", "T 00054"), Coding = c("T 00055_005_<002_+",
"T 00055_008_<002_+", "E 00336_041_<001_+001_+", "E 00336_041_<001_+001_+001_+",
"E 00336_041_<001_+001_+002_+", "E 00336_041_<001_+001_+002_<",
"T 00054_013_<003_<015_+003_<001_<"), Fn = c(2L, 2L, 3L, 4L,
4L, 4L, 4L), Remaining = c(30L, 30L, 0L, 10L, 56L, 52L, 52L)), .Names = c("Object",
"Coding", "Fn", "Remaining"), row.names = c(NA, -7L), class = "data.frame")
subset(df, grepl(rex(at_least(group("_+", anything), 2)), Coding))
#> Object Coding Fn Remaining
#> 3 E00336 E 00336_041_<001_+001_+ 3 0
#> 4 E00336 E 00336_041_<001_+001_+001_+ 4 10
#> 5 E00336 E 00336_041_<001_+001_+002_+ 4 56
#> 6 E00336 E 00336_041_<001_+001_+002_< 4 52