Home > Blockchain >  R: How to make parse() accept regular expressions with escaped characters?
R: How to make parse() accept regular expressions with escaped characters?

Time:05-19

I am trying to use the validator package to check if certain rows in my data table contain a regular expression or not.

I make a vector (fields) with the columns I want to test and then paste together the commands for the validator rules as a string.

To be able to use the rules in the confront() function I use parse() and eval() to turn the character string into an expression

The following example is working as expected:

library(validate)

  data <- data.frame("Protocol_Number" = c("123", "A122"), "Numeric_Result" = c("-0.5", "1.44"))
  fields <- c("Protocol_Number", "Numeric_Result")
  
  # build validator commands for each field
  cmds <- paste("validator(",
                paste(
                  map_chr(
                    fields, function(x) paste0("grepl('^-?[0-9]', as.character(`", x, "`))")
                  ), collapse = ","),
                ")")
  
  # convert to rule and do the tests
  rule <- eval(parse(text = cmds))
  out <- confront(data, rule)
  summary(out)

However, I want to use a regex that recognizes any sort of number as opposed to text, like in this working example

grepl('^-?[0-9]\\d*(\\.\\d )?$', c(1, -1, 0.5, "Not Done"))

When I try to use this regex in the above example, the parse() function will throw an error:

Error: '\d' is an unrecognized escape in character string starting "'^-?[0-9]\d"

This is not working:

  
  # build validator commands for each field
  cmds <- paste("validator(",
                paste(
                  map_chr(
                    fields, function(x) paste0("grepl('^-?[0-9]\\d*(\\.\\d )?$', as.character(`", x, "`))")
                  ), collapse = ","),
                ")")
  
  # convert to rule and do the tests
  rule <- eval(parse(text = cmds))
  out <- confront(data, rule)
  summary(out)

How do I make parse() accept the escaped characters? Or is there a better way to do this?

CodePudding user response:

We may escape it with \\

cmds <- paste("validator(",
                 paste(
                   map_chr(
                     fields, function(x) 
   paste0("grepl('^-?[0-9]\\\\d*(\\\\.\\\\d )?$', as.character(`", x, "`))")
                   ), collapse = ","),
                 ")")

-testing

> rule <- eval(parse(text = cmds))
> 
>  out <- confront(data, rule)
> out
Object of class 'validation'
Call:
    confront(dat = data, x = rule)

Rules confronted: 2
   With fails   : 1
   With missings: 0
   Threw warning: 0
   Threw error  : 0
  • Related