Extract a theme after a dot (in R) - r

I am trying to extract the theme (DPS3_2h) that is after the dot in:
ABBCCAA.DPS3_2h
Using a below command I am able to extract E15 that before the underscore. Not sure how to do it for the above example.
E15_AAACCCAAGAGGCTGT
types <- sub('(.*)_.*', '\\1', colnames(E15))

If you aren't bound to base R, the stringr package offers a lot of nice functions to work with strings. The pattern used here is using a positive look behind (?<=).
stringr::str_extract("ABBCCAA.DPS3_2h",
pattern = "(?<=\\.).*")
#> [1] "DPS3_2h"

Related

Discrepancy between stringr and base R regular expressions

I have this rather annoying to read regular expression.
pattern = "(?<=(?<=[0-9])[dD](?=[0-9]))[0-9]+"
It was generated automatically so human readability or efficiency is less of an issue than validity. It was meant to parse RPG dice type syntax, such as 10d20. Specifically it is supposed to match the 20.
If I use the old method of string matching in R
text = '10d20'
regmatches(text,regexpr(pattern,text,perl = TRUE))
I get what I want, which is 20, however using the more modern method of string matching
stringr::str_match(text, pattern)
I get nothing. I was wondering what causes this difference between the two methods and how can I avoid issues like this in the future.
Unless you need the extras that come with ICU (via stringi which stringr is merely a crutch helper wrapper for) there's no need for woe.
In fact, there's a pkg with less marketing power than tidyverse-based pkgs called stringb which puts "data first" (like string[ir]) and relieves you from base regexp inanity. Vis-a-vis:
library(stringb)
pattern <- "(?<=(?<=[0-9])[dD](?=[0-9]))[0-9]+"
text <- '10d20'
text_extract(text, pattern, perl = TRUE)
## [1] "20"
You get saner syntax without relying on a massive compiled code dependencies and 1-away* stringr abstraction. Bellisimo!
* TBFair: the stringb package also has 1-away abstraction from base R functions but the saner syntax makes up for it IMO (unlike stringr).

Running regex in R using str_extract_all has regexp not yet implemented

I am trying to use regex to parse a file using regex. Most of the solutions to using regex in R use the stringr package. I have not found another way, or another package to use that would work. If you have another way of going about this that would also be acceptable.
What I am trying to accomplish is to grab a couple of values that are seperated by spaces with the last value being some comma seperated values of variable length. This should go into a matrix or df in table like format is it is currently.
foo foo_123bar foo,bar,bazz
foo2 foo_456bar foo2,bar2
I have the working example of my regex here.
There could be a couple of issues I could be running into. The first could be that the regex I am writing is not supported by R's regex engine. Although I have the feeling from this that would be supported. I have seen that R uses a POSIX like format which could make things interesting. The second simply could be exactly what the error message bellow is showing. This is not a feature that has been coded in yet. This however would be the most troubling because I don't know another way to solve my problem without this package.
Below is the R code that I am using to replicate this error
library("stringr")
string = " foo foo_123bar foo,bar,bazz\n foo2 foo_456bar foo2,bar2,bazz2"
pattern = "
(?(DEFINE)
(?<blanks>[[:blank:]]+)
(?<var>\"?[[:alnum:]_]+\"?)
(?<csvar>(\"?[[:alnum:]_]+\"?,?)+)
)
^
(?&blanks)((?&var))
(?&blanks)((?&var))
(?&blanks)((?&csvar))"
# Both of these are throwing the error
str_extract_all(string, pattern)
str_extract_all(string, regex(pattern, multiline=TRUE, comments=TRUE))
> Error in stri_extract_all_regex(string, pattern, simplify = simplify, :
> Use of regexp feature that is not yet implemented. (U_REGEX_UNIMPLEMENTED)
# Using the example from ?str_extract_all runs without error
shopping_list <- c("apples x4", "bag of flour", "bag of sugar", "milk x2")
str_extract_all(shopping_list, "\\b[a-z]+\\b", simplify = TRUE)
I am looking for a solution, not necessarily a stringr solution, but this is the only way I found that fits my needs. The other simpler R regex functions only accept the pattern and not the extra parameters that include the multi line and comment functionality that I am using.
You have a PCRE regex that can only be used in methods/functions that parse the regex with the PCRE regex library (or Boost, it is based on PCRE). stringr str_extract parses the regex with the ICU regex library. ICU regex does not support recursion and DEFINE block. You just can't use the in-pattern approach to define subpatterns and then re-use them.
Instead, just declare the regex parts you need to re-use as variables and build the pattern dynamically:
library("stringr")
string = " foo foo_123bar foo,bar,bazz\n foo2 foo_456bar foo2,bar2,bazz2"
blanks <- "[[:blank:]]+"
vars <- "\"?[[:alnum:]_]+\"?"
csvar <- "(?:\"?[[:alnum:]_]+\"?,?)+"
pattern <- paste0("^",blanks,"(", vars, ")",blanks,"(", vars,")",blanks,"(",csvar, ")")
str_match_all(string, pattern)
# [[1]]
# [,1] [,2] [,3] [,4]
#[1,] " foo foo_123bar foo,bar,bazz" "foo" "foo_123bar" "foo,bar,bazz"
Note: you need to use str_match (or str_match_all) to extract the capturing group values as str_extract or str_extract_all only allows access to the whole match values.

Searching for words in a corpus with R

I am trying to search for strings of words in a corpus using R. Are disjunctive statements allowed in grep, e.g., grep("a" or "b" or "c"...)? If so, once I have that subcorpus, how do I then refine it further to contain only those examples with at least two tokens of the original condition?
Yes, the vertical bar | works as an or-operator in grep. You can look up regular expressions in R by running ?regex.
So, to give an example:
grep("ape|bass|cat", c("monkey", "bass", "catfish"))
[1] 2 3
Also confer the documentation of grep, grepl, and that family of functions.
The stringr package provide additional tools for handling text.

stargazer and omit regular expressions

I am trying to use regular expressions to omit some variables in stargazer. I finally found a working regex, but it's using the Perl standard. This doesn't work for the base regex in R, though regexpr in R can take a perl=T option. Given that you wrap the regex for variable sets to omit in "", you can't really pass it this option. Any ideas on how to use perl regex with stargazer?
An example of the regex I would like to use is
placed.ind2*(?:(?!:switchind).)*$
applied to these 4 strings:
placed.ind2PROF SERVICES
placed.ind2TRANSPORT
placed.ind2PROF SERVICES:switchind2TRUE
placed.ind2TRANSPORT:switchind2TRUE
I would like the first two to be selected, but the last to be.
Starting from version 4.0 (on CRAN now), you can run stargazer with the argument perl=TRUE to allow for Perl-compatible regular expressions in your other arguments.

How to use variable in xpath in R?

when i parse a web file, it works fine ,
tdata=xpathApply(data,"//table[#id='PL']")
i want to use variable in xpathApply,
x="PL"
tdata=xpathApply(data,"//table[#id=x]")
it can not work,how to write the xpath expression in xpathApply with variable?
think for Dason's suggestion,
x="PL"
y=paste0("//table[#id='",x,"']")
tdata=xpathApply(data,y)
it is ok,but i feel it is ugly,how can i write it more beautiful?
The gsubfn package can do string interpolation somewhat along the lines of Perl if we preface the function whose arguments are to contain substitutions with fn$. Here $x means substitute in the value of x . See ?fn and the gsubfn home page.
library(gsubfn)
x <- "PL"
tdata <- fn$xpathApply(data, "//table[#id='$x']")
#Dason's suggestion of using paste or one alike is most likely the only way to go. If you find it ugly, you can sweep it under the rug by creating your own function:
my.xpathApply <- function(data, x) xpathApply(data, paste0("//table[#id='",x,"']"))
tdata <- my.xpathApply(data, "PL")
After all, you must use a lot of package functions that use paste somewhere, so you should be ok with having one of your own :-)

Resources