Reputation: 85
I am trying to use a function that models nesting success of birds using a logistic exposure link function.
When I run this function using the example code above in R 3.0.0 or 3.0.1, I get the error:
Error in .Call("logit_mu_eta", eta, PACKAGE = "stats") :
"logit_mu_eta" not available for .Call() for package "stats"
However, it works fine in R 2.15.3.
I'd like for this to work in more recent versions of R, since I use those for further analysis of the outputs. If anybody has any suggestions, workarounds or corrections, I'd happily try them.
Upvotes: 5
Views: 1997
Reputation: 226087
This is not technically a bug, since the function used an internal function whose location has now changed. I have a working example of this posted at https://rpubs.com/bbolker/logregexp ... the key is changing logit_mu_eta
to stats:::C_logit_mu_eta
as below. Of course, this will still be fragile to future changes in the internals ...
logexp <- function(exposure = 1)
{
linkfun <- function(mu) qlogis(mu^(1/exposure))
## FIXME: is there some trick we can play here to allow
## evaluation in the context of the 'data' argument?
linkinv <- function(eta) plogis(eta)^exposure
mu.eta <- function(eta) exposure * plogis(eta)^(exposure-1) *
.Call(stats:::C_logit_mu_eta, eta, PACKAGE = "stats")
valideta <- function(eta) TRUE
link <- paste("logexp(", deparse(substitute(exposure)), ")",
sep="")
structure(list(linkfun = linkfun, linkinv = linkinv,
mu.eta = mu.eta, valideta = valideta,
name = link),
class = "link-glm")
}
Upvotes: 4
Reputation: 15163
That's odd. Might be a bug. You might want to send this to the R mailing list and see what they think. As a crude workaround, you could rewrite that function in R. Here's the C code for it, from the file family.c in src/library/stats/src/:
SEXP logit_mu_eta(SEXP eta)
{
SEXP ans = PROTECT(duplicate(eta));
int i, n = LENGTH(eta);
double *rans = REAL(ans), *reta = REAL(eta);
if (!n || !isReal(eta))
error(_("Argument %s must be a nonempty numeric vector"), "eta");
for (i = 0; i < n; i++) {
double etai = reta[i];
double opexp = 1 + exp(etai);
rans[i] = (etai > THRESH || etai < MTHRESH) ? DOUBLE_EPS :
exp(etai)/(opexp * opexp);
}
UNPROTECT(1);
return ans;
}
THRESH
is defined to be 30. So it looks like you could replace the external call with this function:
logit_mu_eta<-function(x){
ex<-exp(x)
ans<-ex/(1+ex)^2
ans[abs(x)>30]<-.Machine$double.eps
ans
}
Then you'd have to modify whatever function is calling this.
Upvotes: 0