0

I need a way to call defined variables dependant from a string within text. Let's say I have five variables (r010, r020, r030, r040, r050). If there is a given text in that form "r010-050" I want to have the sum of values from all five variables.

The whole text would look like "{r010-050} == {r060}" The first part of that equation needs to be replaced by the sum of the five variables and since r060 is also a variable the result (via parsing the text) should be a logical value.

I think regex will help here again. Can anyone help? Thanks.

Sven
  • 83
  • 10

1 Answers1

1

Define the inputs: the variables r010 etc. which we assume are scalars and the string s.

Then define a pattern pat which matches the {...} part and a function Sum which accepts the 3 capture groups in pat (i.e. the strings matched to the parts of pat within parentheses) and performs the desired sum.

Use gsubfn to match the pattern, passing the capture groups to Sum and replacing the match with the output of Sum. Then evaluate it.

In the example the only variables in the global environment whose names are between r010 and r050 inclusive are r010 and r020 (it would have used more had they existed) and since they sum to r060 it returned TRUE.

library(gsubfn)

# inputs
r010 <- 1; r020 <- 2; r060 <- 3
s <- "{r010-050} == {r060}"

pat <- "[{](\\w+)(-(\\w+))?[}]"
Sum <- function(x1, x2, x3, env = .GlobalEnv) {
  x3 <- if(x3 == "") x1 else paste0(gsub("\\d", "", x1), x3)
  lst <- ls(env)
  sum(unlist(mget(lst[lst >= x1 & lst <= x3], envir = env)))
}
eval(parse(text = gsubfn(pat, Sum, s)))
## [1] TRUE
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341
  • Thanks. How does the code have to be changed if the `s` looks hardcore like `{r180} * (sum(r010-100, r130, r150) - {r160}) == {r110} `? Here, five steps of Evaluation have to be done, first the sum of r010 to r100, second the sum of the sum brackets, third the difference, forth the multiplication, fifth the equation... Can you please help here? – Sven Mar 13 '18 at 16:32
  • Write the input like this and the existing code will work assuming you have appropriately defined the r... variables: `s <- "{r180} * (sum({r010-100}, {r130}, {r150}) - {r160}) == {r110}"` – G. Grothendieck Mar 13 '18 at 20:58
  • If `s` is like `sum(c010, c020, c030, c110-130, c150, c170) == {c180}` and `pat` is changed to `(\\w+)(-(\\w+))?` the result of `b <- gsubfn(pat, Sum, s); eval(parse(text = b))` will be `0(498278, 470925, 459064, 1494628, 510047, 520594) == {489302}`... So it seems the formula works, but the word `sum` is replaced by a `0` .. what has to be changed so that the `sum`-command remains and the result of the eval is the Logical value in the end? Thanks – Sven Mar 26 '18 at 10:31