简体   繁体   中英

F# RProvider strange behavior in mgcv package

This works:

// 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

The gam() output is

Family: gaussian Link function: identity

Formula: y ~ x0 + s(x1) + s(x2) + s(x3)

Estimated degrees of freedom: 1.73 7.07 1.00 total = 13.8

GCV score: 4.578643

and the anova() output is

Family: gaussian Link function: identity

Formula: y ~ x0 + s(x1) + s(x2) + s(x3)

Parametric Terms: df F p-value x0 3 77.42 <2e-16

Approximate significance of smooth terms: edf Ref.df F p-value s(x1) 1.729 2.158 45.071 <2e-16 s(x2) 7.069 8.120 49.230 <2e-16 s(x3) 1.000 1.000 0.056 0.812

However, if I try to call the function using the RProvider (an F# type provider) like this:

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)

the following error is generated:

RDotNet.EvaluationException: Error in terms.formula(gf, specials = c("s", "te", "ti", "t2")) : argument is not a valid model

this error happens on the gam() line. I found the offending line in https://svn.r-project.org/R-packages/trunk/mgcv/R/mgcv.r , but I'm not sure what's going wrong:

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

However, when I combine elements of the two like this:

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)

it runs just fine. Note that there are two changes. The first is loading the library, which RProvider I thought was supposed to do for you. The second is using evalS to wrap the formula. I call R.lm without doing this (I just pass in a string representing the formula), so I'm confused as to why this doesn't work the same way.

Can anyone explain this? Is it a bug or just undocumented, but correct, behavior? This is running in ifsharp BTW ( https://github.com/BayardRock/IfSharp )

I'm only guessing (have not actually tried running the code), but I think the problem is that the formula argument of the gam function is not actually just a string (which is how you call it in the second case), but a symbolic expression.

R has quite fancy parameter passing mechanism where the function gets a source code representation of y~x0+s(x1)+s(x2)+s(x3) so that it can do the analysis based on the expression you specify.

When you pass it through evalS , you're calling R to build the symbolic expression, which you then pass to the gam function - and so it gets an expression rather than a string . This is also what happens in the first snippet (where R engine parses the whole string).

As for having to write library(mgcv) , I suspect doing that imports some of the symbols used in the symbolic expression like s(...) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM