在 R 中将表达式转换为函数
Conversion of expression to function in R
我有一个布尔表达式列表,我需要在随机生成的起点(数据矩阵的行)处对其进行评估。我正在尝试在 R 中编写一个包装函数,它可以提取列表 g 的每个元素并将其转换为可以计算的函数。例如,见列表 g,第一个元素是 (!x[2] & !x[3]) | (!x[2] & x[3]) | (x[2] & x[3]) 我想把它写成
函数(x){(!x[2] & !x[3]) | (!x[2] & x[3]) | (x[2] & x[3])} 这样我就可以按以下方式评估数据矩阵的行。我想对列表 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
我写了这个包装函数,但它不起作用,我不知道我做错了什么。我是编写 R 函数的新手,希望得到帮助。
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)
}
您要做的是解析和评估字符串。这可以通过下面的 E
函数来完成:
E <- function (...) {eval(parse(text=paste(...,collapse=" ")))}
然后从字符串生成函数的包装函数变为:
wrapper <- function(s){E("function(x){",s,"}")}
您可以将其应用于 g
以生成您的函数列表:
ListOfFunctions <- lapply(g, wrapper)
要实现这一点,g
可以简单地作为您给出的字符串列表,不需要 "noquote" 属性。
我还不清楚你想如何将它与你的矩阵一起使用。
这已交叉发布到 Rhelp(形式略有不同),其中 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))
我使用上面提供的结构对其进行了测试,解决方案确实成功了。我认为他不会介意在这里重复这一点。
我有一个布尔表达式列表,我需要在随机生成的起点(数据矩阵的行)处对其进行评估。我正在尝试在 R 中编写一个包装函数,它可以提取列表 g 的每个元素并将其转换为可以计算的函数。例如,见列表 g,第一个元素是 (!x[2] & !x[3]) | (!x[2] & x[3]) | (x[2] & x[3]) 我想把它写成 函数(x){(!x[2] & !x[3]) | (!x[2] & x[3]) | (x[2] & x[3])} 这样我就可以按以下方式评估数据矩阵的行。我想对列表 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
我写了这个包装函数,但它不起作用,我不知道我做错了什么。我是编写 R 函数的新手,希望得到帮助。
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)
}
您要做的是解析和评估字符串。这可以通过下面的 E
函数来完成:
E <- function (...) {eval(parse(text=paste(...,collapse=" ")))}
然后从字符串生成函数的包装函数变为:
wrapper <- function(s){E("function(x){",s,"}")}
您可以将其应用于 g
以生成您的函数列表:
ListOfFunctions <- lapply(g, wrapper)
要实现这一点,g
可以简单地作为您给出的字符串列表,不需要 "noquote" 属性。
我还不清楚你想如何将它与你的矩阵一起使用。
这已交叉发布到 Rhelp(形式略有不同),其中 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))
我使用上面提供的结构对其进行了测试,解决方案确实成功了。我认为他不会介意在这里重复这一点。