在 glm 函数中使用二项式时,lazyeval 未找到“C_logit_link”
lazyeval not finding `C_logit_link` when using binomial in the glm function
我真的很挠头。我真的不明白这是怎么回事。这是一个 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()
)
)
哪个returns: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 代码。这是统计数据包中未导出的对象。通常一切正常,因为该函数的环境是 stats 命名空间,因此它能够找到 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
我真的很挠头。我真的不明白这是怎么回事。这是一个 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()
)
)
哪个returns: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 代码。这是统计数据包中未导出的对象。通常一切正常,因为该函数的环境是 stats 命名空间,因此它能够找到 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