R String processing
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Here’s a little vignette of data munging using the regular expression facilities of R (aka the R-project for statistical computing). Let’s say I have a vector of strings that looks like this:
> coords [1] "chromosome+:157470-158370" "chromosome+:158370-158450" "chromosome+:158450-158510" [4] "chromosome+:158510-159330" "chromosome-:157460-158560" "chromosome-:158560-158920"
What I’d like to do is parse these out into a data.frame with a column for each of sequence, strand, start, end. A regex that would do that kind of thing looks like this: (.*)([+-]):(d+)-(d+). R does regular expressions, but it’s missing a few pieces. For example, in python you might say:
import re coords = """ chromosome+:157470-158370 chromosome+:158370-158450 chromosome+:158450-158510 chromosome+:158510-159330 chromosome-:157460-158560 chromosome-:158560-158920 """ regex = re.compile("(.*)([+-]):(\d+)-(\d+)") for line in coords.split("n"): line = line.strip() if (len(line)==0): continue m = regex.match(line) if (m): seq = m.group(1) strand = m.group(2) start = int(m.group(3)) end = int(m.group(4)) print "%st%st%dt%d" % (seq, strand, start, end)
As far as I’ve found, there doesn’t seem to be an equivalent in R to regex.match, which is a shame. The gsub function supports capturing groups in regular expressions, but isn’t very flexible about what you do with them. One way to solve this problem is to use gsub to pull out each individual column. Not efficient, but it works:
> coords.df = data.frame( seq=gsub("(.*)([+-]):(\d+)-(\d+)", "\1", row.names(m), perl=T), strand=gsub("(.*)([+-]):(\d+)-(\d+)", "\2", row.names(m), perl=T), start=as.integer(gsub("(.*)([+-]):(\d+)-(\d+)", "\3", row.names(m), perl=T)), end=as.integer(gsub("(.*)([+-]):(\d+)-(\d+)", "\4", row.names(m), perl=T))) > coords.df seq strand start end 1 chromosome + 157470 158370 2 chromosome + 158370 158450 3 chromosome + 158450 158510 4 chromosome + 158510 159330 5 chromosome - 157460 158560 6 chromosome - 158560 158920
It seems strange that R doesn’t have a more direct way of accomplishing this. I’m not an R expert, so maybe it’s there and I’m missing it. I guess it’s not called the R project for string processing, but still… By the way, if you’re ever tempted to name a project with a single letter, consider the poor schmucks trying to google for help.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.