R- LazyEval在GLM函数中使用二项式时找不到`c_logit_link`



我真的在这里挠头。我真的不明白发生了什么。这是MWE,但实际的代码和目的比这更复杂。因此,代码:

library(dplyr)
ds <- mutate(iris, Species = as.numeric(Species == 'setosa'))
ds %>%
    do_(
        .dots = lazyeval::interp(
            "broom::tidy(stats::glm(form, data = ., family = distr))",
            form = Species ~ Sepal.Length,
            distr = binomial()
        )
    )

返回:Error in family$linkfun(mustart) : object 'C_logit_link' not found ...但是此代码位正常:

ds %>%
    do_(
        .dots = lazyeval::interp(
            "broom::tidy(stats::glm(form, data = ., family = distr))",
            form = Sepal.Width ~ Sepal.Length,
            distr = gaussian()
        )
    )

两者之间的唯一区别是使用的家庭分布(高斯与二项式)和所使用的变量。

所以问题:为什么LazyeVal找不到C_logit_link

调用 interp(x, *)时,它会评估要插入x的参数。在binomial()的情况下,结果是代表GLM中二项式分布的结构。

interp(~x, x=binomial())
#~list(family = "binomial", link = "logit", linkfun = function (mu) 
#.Call(C_logit_link, mu), linkinv = function (eta) 
#.Call(C_logit_linkinv, eta), variance = function (mu) 
#mu * (1 - mu), dev.resids = function (y, mu, wt) 
#.Call(C_binomial_dev_resids, y, mu, wt), aic = function (y, n, 
#    mu, wt, dev) 
#{
#    m <- if (any(n > 1)) 
#    . . .

埋在该结构内部是通过对象C_logit_link呼叫编译C代码的函数。这是统计包中的一个未出现的对象。通常一切正常,因为该功能的环境是统计名称空间,因此它可以找到C_logit_link

这里的问题在于,您要插值的对象是字符串,这意味着将其插入其中的所有内容也被强制为字符串。失去查找C_logit_link所需的环境信息。

解决方案是插入公式:

library(dplyr)
ds <- mutate(iris, Species = as.numeric(Species == 'setosa'))
ds %>%
    do_(
        .dots = lazyeval::interp(
            ~broom::tidy(stats::glm(form, data = ., family = distr)),  # formula
            form = Species ~ Sepal.Length,
            distr = binomial()
        )
    )
#          term  estimate std.error statistic      p.value
#1  (Intercept) 27.828521 4.8275611  5.764509 8.189574e-09
#2 Sepal.Length -5.175698 0.8933984 -5.793270 6.902910e-09

最新更新