【问题标题】:passing model parameters to R's predict() function robustly将模型参数稳健地传递给 R 的 predict() 函数
【发布时间】:2015-08-16 23:23:00
【问题描述】:

我正在尝试使用 R 来拟合线性模型并进行预测。我的模型包括一些不在数据框中的常量边参数。这是我正在做的简化版本:

dat <- data.frame(x=1:5,y=3*(1:5))
b <- 1
mdl <- lm(y~I(b*x),data=dat)

不幸的是,模型对象现在遇到了一个危险的作用域问题:lm() 不会将b 保存为mdl 的一部分,因此当调用predict() 时,它必须回到@987654326 所在的环境中@ 已定义。因此,如果后续代码改变b的值,预测值也会改变:

y1 <- predict(mdl,newdata=data.frame(x=3)) # y1 == 9
b <- 5
y2 <- predict(mdl,newdata=data.frame(x=3)) # y2 == 45

如何强制predict() 使用原始b 值而不是更改后的值?或者,是否有某种方法可以控制predict() 查找变量的位置,以便我可以确保它获得所需的值?在实践中,我不能将b 作为newdata 数据框的一部分,因为在我的应用程序中,b 是一个参数向量,其大小与新观察的数据框不同。

请注意,相对于我的实际用例,我已经大大简化了这一点,因此我需要一个强大的通用解决方案,而不仅仅是临时黑客。

【问题讨论】:

    标签: r lexical-scope dynamic-scope


    【解决方案1】:

    eval(substitute 将值放入带引号的表达式中

    mdl <- eval(substitute(lm(y~I(b*x),data=dat), list(b=b)))
    
    mdl
    # Call:
    # lm(formula = y ~ I(1 * x), data = dat)
    # ...
    

    【讨论】:

    • 哇,太棒了。唯一的缺点是它使str(mdl) 更难看,因为它充满了替换值。但我现在可以忍受,除非你能想到更好的方法?谢谢!
    • @Paul 我不确定你的意思?因为有数字代替“b”?还是别的什么?
    • @Paul 好的,试试mdl &lt;- local({b=b; lm(y ~ I(b*x), data=dat) }),也许这样更漂亮
    • @Paul 你可能只想阅读?local 文档(环境的东西可能会令人困惑,它会比我做得更好),但local 创建了一个新的环境,你可以为表达式定义变量。例如,如果您改为使用mdl &lt;- local({ b=b; lm(y ~ I(b*x), data=dat) }, envir=.GlobalEnv),则在全局环境中重新定义b 时将不起作用。
    • 谢谢。阅读文档后,我对local() 产生的新环境的居住地感到有些困惑。但我发现这段代码很有启发性:my_env=new.env(); mdl &lt;- local({b&lt;-1; lm(y ~ I(b*x), data=dat) },envir=my_env); ls(my_env),它输出"b"
    【解决方案2】:

    我们也可以使用bquote

    mdl <- eval(bquote(lm(y~I(.(b)*x), data=dat)))
    mdl
    
    #Call:
    #lm(formula = y ~ I(1 * x), data = dat)
    
    #Coefficients:
    #(Intercept)     I(1 * x)  
    #  9.533e-15    3.000e+00  
    

    根据?bquote描述

    ‘bquote’引用它的 参数,除了包裹在“.()”中的术语在 指定“where”环境。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-05
      • 1970-01-01
      • 1970-01-01
      • 2012-06-07
      • 2021-10-26
      • 1970-01-01
      相关资源
      最近更新 更多