F#RProvider在mgcv包中的奇怪行为

时间:2014-06-20 03:36:57

标签: r f# type-providers

这有效:

// Helper that evaluates R expression
let evalS (text:string) =
  R.eval(R.parse(namedParams ["text", text ]))

let evalV (text:string) =
  (text |> evalS).Value

//run example from page 8 of http://cran.r-project.org/web/packages/mgcv/mgcv.pdf
evalV("""
    library(mgcv)
    set.seed(0)
    dat <- gamSim(5,n=200,scale=2)
    """)
let am1 = evalS("b<-gam(y ~ x0 + s(x1) + s(x2) + s(x3),data=dat)")
let gam_anova1 = evalS("anova(b)")
am1.Value

gam()输出

  

家庭:高斯链接功能:身份

     

公式:y~x0 + s(x1)+ s(x2)+ s(x3)

     

估计自由度:   1.73 7.07 1.00总计= 13.8

     

GCV得分:4.578643

和anova()输出

  

家庭:高斯链接功能:身份

     

公式:y~x0 + s(x1)+ s(x2)+ s(x3)

     

参数术语:df F p值x0 3 77.42&lt; 2e-16

     

平滑术语的近似重要性:           edf Ref.df F p值s(x1)1.729 2.158 45.071&lt; 2e-16 s(x2)7.069 8.120 49.230&lt; 2e-16 s(x3)1.000 1.000 0.056 0.812

但是,如果我尝试使用RProvider(一个F#类型提供者)调用该函数,如下所示:

open RProvider.mgcv
R.set_seed(0)
let dat = R.gamSim(5,n=200,scale=2)
let b = R.gam(formula = "y~x0+s(x1)+s(x2)+s(x3)",data=dat)
R.anova_gam(b)

生成以下错误:

  

RDotNet.EvaluationException:terms.formula中的错误(gf,specials =   c(&#34; s&#34;,&#34; te&#34;,&#34; ti&#34;,&#34; t2&#34;)):参数不是有效模型

这个错误发生在gam()行上。我在https://svn.r-project.org/R-packages/trunk/mgcv/R/mgcv.r找到了违规行,但我不确定出了什么问题:

tf <- terms.formula(gf,specials=c("s","te","ti","t2")) # specials attribute indicates which terms are smooth

然而,当我将两者的元素组合在一起时:

evalV("""
    library(mgcv)
    """)
open RProvider.mgcv
R.set_seed(0)
let dat = R.gamSim(5,n=200,scale=2)
let b = R.gam(formula = evalS("y~x0+s(x1)+s(x2)+s(x3)"),data=dat)
//let b = R.gam(formula = "y~x0+s(x1)+s(x2)+s(x3)",data=dat)
R.anova_gam(b)

它运行得很好。请注意,有两处更改。第一个是加载库,我认为RProvider应该为你做。第二个是使用evalS来包装公式。我在没有这样做的情况下调用R.lm(我只是传入一个代表公式的字符串),所以我很困惑为什么它不会以同样的方式工作。

任何人都能解释一下吗?它是一个bug还是只是没有记录,但是正确的行为?这是在ifsharp BTW(https://github.com/BayardRock/IfSharp

中运行的

1 个答案:

答案 0 :(得分:1)

我只猜测(实际上没有尝试过运行代码),但我认为问题是formula函数的gam参数实际上并不只是一个字符串(其中是你在第二种情况下称之为的方式),而是一种象征性的表达方式。

R具有非常精美的参数传递机制,其中函数获取y~x0+s(x1)+s(x2)+s(x3)源代码表示,以便它可以根据您指定的表达式进行分析。

当您通过evalS传递时,您正在调用R来构建符号表达式,然后将其传递给gam函数 - 这样它就会得到表达式< / em>而不是字符串。这也是第一个片段(R引擎解析整个字符串)中发生的情况。

至于必须写library(mgcv),我怀疑这样做会导入符号表达式中使用的一些符号,如s(...)