将类型“语言”转换为“表达式”

3

我是新手R语言,常常被其他语言中不存在或者我不需要的数据结构所困惑。

目前,我正在尝试将“language”类型的对象转换为“expression”,以便进行绘图。

首先,我创建了要绘制的函数:

> model <- nls(y~a+b*exp(x*z),start = list(a=1, b = -.5, z = -.8),data=results)  
> modelsym <- substitute(a+b*exp(z*x), list(a=coef(model[1],b=coef(model)[2],z=coef(model)[3]))

该函数的类型为“语言”:
> modelsym  
0.958945264470923 + -0.463676594301167 * exp(-0.155697065390677 * x)  
> typeof(modelsym)  
[1] "language"

如果我尝试绘制这条曲线:

> curve(modelsym)  
Error in eval(expr, envir, enclos) : could not find function "modelsym"

然而,如果我复制粘贴它就能正常工作:
> curve(0.958945264470923 + -0.463676594301167 * exp(-0.155697065390677 * x))  
**[plot appears here]**

我尝试过as(modelsym,expression)但没有成功。如何将我的对象modelsym转换为expression以便绘图?

你能展示一下 modelsym 是如何创建的吗?这样我们就可以确保使用的是完全相同的东西。 - Gavin Simpson
@GavinSimpson,好的,我刚刚编辑了我的原始问题。 - Jeff
FYI,我刚刚想出了一个解决方法:plot(eval(modelsym),type='line')可以工作,但仍然想知道我的原始问题的答案... - Jeff
2个回答

3
这不是一个完整的解决方案,但我已经接近成功了:
do.call(curve, list(expr = modelsym))

这实际上为您安排了一个调用curve的过程,其中expr参数设置为modelsym的内容。

您尝试失败的原因是curve的第一行是

sexpr <- substitute(expr)

当传递一个包含语句的对象(任何对象都可以)时,会得到以下结果:

Browse[2]> sexpr
modelsym
Browse[2]> is.call(sexpr)
[1] FALSE
Browse[2]> is.expression(sexpr)
[1] FALSE

这两个测试是curve用来确定输入是否可接受的。

无论你传递什么给curve,它都需要是一个实际的语句,而不是包含一个语句的调用。


2
我认为这是curve中的一个错误,因为每当您将对象传递给expr时,is.name(sexpr)都会为真。此外,您正在以两种略微不兼容的方式使用表达式。口语上,表达式是引用的(未评估的)调用,但这不是is.expression测试的内容(类似于is.vector不测试对象是否为向量)。 - hadley
1
虽然我同意 Hadley 的观点,认为在这里谈论表达式(尤其是使用 is.expression 进行测试)可能会因其在此上下文中的多种含义而具有误导性。 (即使是 R 文档在这方面有时也令人困惑。)+1 解决方案。 - Josh O'Brien
我只展示了is.expression的输出,因为这是curve在替换输入上使用的测试,但我同意术语很令人困惑。感谢你们的评论。 - Gavin Simpson
@GavinSimpson - 我认为这些术语很好。R-lang 做了类似的事情,说“特别是语法正确的表达式将被称为语句”。在您帖子的最后一行中,我会将“not an expression object ...”编辑为“not a symbol containing one as its value”,因为 modelsym 本身不是一个表达式对象。相反,它是一个其值为表达式对象的符号。只是我的个人意见。 - Josh O'Brien
@JoshO'Brien 感谢您的深思熟虑的评论。在进一步思考并创建类似于OP的东西时,“modelsym”是一种调用(模式“调用”)。它不是is.symbol中所指的那种符号。 - Gavin Simpson
显示剩余2条评论

3
使用predict是另一个解决方案:
model <- nls(y~a+b*exp(x*z),start = list(a=1, b = -.5, z = -.8),data=results)

modelf <- function(x) predict(model, newdata = data.frame(x = x))
plot(modelf)
curve(modelf)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接