user24318
user24318

Reputation: 485

Conversion of expression to function in R

I have a list of boolean expressions that I need to evaluate at randomly generated starting points(rows of data matrix). I am trying to write a wrapper function in R that can extract each element of the list g and convert it into a function that can be evaluated. For example, see list g, the first element is (!x[2] & !x[3]) | (!x[2] & x[3]) | (x[2] & x[3]) and I want to write it as function(x){(!x[2] & !x[3]) | (!x[2] & x[3]) | (x[2] & x[3])} so that I can evaluate at rows of data matrix in the following way. I want to do this for all elements of list g.

h1<-function(x){(!x[2] & !x[3]) | (!x[2] & x[3]) | (x[2] & x[3])} 
h1(data[,1])
[1] TRUE
 h1(data[2,])
[1] TRUE

g<-list(structure("(!x[2] & !x[3]) | (!x[2] & x[3]) | (x[2] & x[3])", class = "noquote"), 
    structure("(!x[2] & !x[1]) | (!x[2] & x[1]) | (x[2] & !x[1])", class = "noquote"), 
    structure("(!x[2] & x[3]) | (x[2] & !x[3])", class = "noquote"))

> g
[[1]]
[1] (!x[2] & !x[3]) | (!x[2] & x[3]) | (x[2] & x[3])

[[2]]
[1] (!x[2] & !x[1]) | (!x[2] & x[1]) | (x[2] & !x[1])

[[3]]
[1] (!x[2] & x[3]) | (x[2] & !x[3])

gendata <- function(n,p ) {
  matrix(rbinom(n * p, 1, 0.5), ncol = p, nrow = n)
}

data<-gendata(5,3)
 data
 [,1] [,2] [,3]
[1,]    0    0    0
[2,]    1    1    1
[3,]    1    0    1
[4,]    1    1    1
[5,]    1    1    0

I wrote this wrapper function but it does not work and I do not know what am I doing wrong. I am new to writing R functions and will appreciate help.

wrapper <-function(y) {function(x) {(y)}} 
lapply(g,wrapper)
    [[1]]
    function (x) 
    {
    (y)
}
<environment: 0x0000000008d848f8>

 [[2]]
 function (x) 
 {
    (y)
}
 <environment: 0x0000000008d84a80>

[[3]]
function (x) 
{
(y)
 }

Upvotes: 1

Views: 866

Answers (2)

IRTFM
IRTFM

Reputation: 263481

This was crossposted to Rhelp (in a slightly different form) where Uwe Ligges offered the following solution:

#One way:

f <- function(x) x
gfunc <- lapply(g, function(i) {body(f) <- parse(text=i); f})

# So now you have functions in your list gfunc and can call them via

gfunc[[1]](c(0,0,0))

I tested it using the structure offered above and the solution does succeed. I don't think he will mind having this repeated here.

Upvotes: 1

cmbarbu
cmbarbu

Reputation: 4532

What you are trying to do is to parse and evaluate a string. This can be done by the E function hereafter:

E <- function (...) {eval(parse(text=paste(...,collapse=" ")))}

Then your wrapper function that generates functions from the strings becomes:

wrapper <- function(s){E("function(x){",s,"}")}

And you can apply it to g to generate your list of functions:

ListOfFunctions <- lapply(g, wrapper)

For this to work, g can simply be a list of the strings you give as example, no need for the "noquote" attribute.

It is still unclear to me how you want to use that with your matrix.

Upvotes: 2

Related Questions