问题
Data: Data
Code:
#function that calculates ‘the average of the sample marginal effects’.
mfxboot <- function(modform,dist,data,boot=1000,digits=3){
x <- glm(modform, family=binomial(link=dist),data)
# get marginal effects
pdf <- ifelse(dist=="probit",
mean(dnorm(predict(x, type = "link"))),
mean(dlogis(predict(x, type = "link"))))
marginal.effects <- pdf*coef(x)
# start bootstrap
bootvals <- matrix(rep(NA,boot*length(coef(x))), nrow=boot)
set.seed(1111)
for(i in 1:boot){
samp1 <- data[sample(1:dim(data)[1],replace=T,dim(data)[1]),]
x1 <- glm(modform, family=binomial(link=dist),samp1)
pdf1 <- ifelse(dist=="probit",
mean(dnorm(predict(x, type = "link"))),
mean(dlogis(predict(x, type = "link"))))
bootvals[i,] <- pdf1*coef(x1)
}
res <- cbind(marginal.effects,apply(bootvals,2,sd),marginal.effects/apply(bootvals,2,sd))
if(names(x$coefficients[1])=="(Intercept)"){
res1 <- res[2:nrow(res),]
res2 <- matrix(as.numeric(sprintf(paste("%.",paste(digits,"f",sep=""),sep=""),res1)),nrow=dim(res1)[1])
rownames(res2) <- rownames(res1)
} else {
res2 <- matrix(as.numeric(sprintf(paste("%.",paste(digits,"f",sep=""),sep="")),nrow=dim(res)[1]))
rownames(res2) <- rownames(res)
}
colnames(res2) <- c("marginal.effect","standard.error","z.ratio")
return(res2)
}
## Regression
probit_enae = glm(emploi ~ genre + filiere + satisfaction + competence + anglais, family=binomial(link="probit"),
data=ENAE_Probit.df)
summary(probit_enae) #Summary output of the regression
confint(probit_enae) #Gives the 95% confidence interval for the estimated coefficients
## Running the mfxboot for Marginal effects
mfx_enae = mfxboot(emploi ~ genre + filiere + satisfaction + competence + anglais,"probit",ENAE_Probit.df)
Question:
When I run the mfxboot function, I get the following error message:
Error in bootvals[i, ] <- pdf1 * coef(x1) : number of items to replace is not a multiple of replacement length
Any idea as to why that happens? And Any suggestion of how to go around this issue?
Thanks.
回答1:
I am not able to reproduce your error. Perhaps you should add sessionInfo()
output to your question. A suggested enhancement to the mfxboot
function follows below nonetheless.
My suggestion would be to refactor the mfxboot
function into two functions -- one
that returns the marginal effects given a glm
object, and the second which
bootstraps it.
You can do this easily using the Boot function in the car
package since
that is a nice front-end for bootstrapping glm
objects.
Here is some code that demonstrates this process, which is much cleaner to read:
Step 1: Estimate a probit model
library(car)
#================================================
# read in data, and estimate a probit model
#================================================
dfE = read.csv("ENAE_Probit.csv")
formE = emploi ~ genre +
filiere + satisfaction + competence + anglais
glmE = glm(formula = formE,
family = binomial(link = "probit"),
data = dfE)
Step 2: Write a function that returns the marginal effects
The following function takes as input a glm
object of the binomial
family and computes appropriate marginal effects for logit and probit links.
#================================================
# function: compute marginal effects for logit and probit models
# NOTE: this assumes that an intercept has been included by default
#================================================
fnMargEffBin = function(objBinGLM) {
stopifnot(objBinGLM$family$family == "binomial")
vMargEff = switch(objBinGLM$family$link,
probit = colMeans(outer(dnorm(predict(objBinGLM,
type = "link")),
coef(objBinGLM))[, -1]),
logit = colMeans(outer(dlogis(predict(objBinGLM,
type = "link")),
coef(objBinGLM))[, -1])
)
return(vMargEff)
}
# test the function
fnMargEffBin(glmE)
Step 3: Bootstrap the marginal effects
The following code uses the Boot
function from the car
package to bootstrap the marginal effects. Note how the interface of Boot
is optimized for statistics derived from lm
and glm
objects.
#================================================
# compute bootstrap std. err. for the marginal effects
#================================================
margEffBootE = Boot(object = glmE, f = fnMargEffBin,
labels = names(coef(glmE))[-1], R = 100)
summary(margEffBootE)
Here is the output:
> summary(margEffBootE)
R original bootBias bootSE bootMed
genre 100 0.070733 0.00654606 0.042162 0.074563
filiere 100 0.043173 0.00060356 0.014064 0.043486
satisfaction 100 0.050773 -0.00110501 0.037737 0.048310
competence 100 -0.020144 0.00407027 0.034194 -0.014987
anglais 100 -0.018906 -0.00170887 0.033522 -0.019164
来源:https://stackoverflow.com/questions/26489859/mfxboot-function-for-marginal-effects-for-probit-regressions