Reputation: 485
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
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
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