delta method using numerical derivative. An example
The main conclusions are :
- Use delta method with or without analytic derivative, it does not change anything
- Do not use simple resampling using SD
- You can use resampling taking into variance-covariance matrix
library(car)
m1 <- lm(time ~ t1 + t2, data = Transact)
result <- deltaMethod(coef(m1), "t1/t2", vcov.=vcov(m1))
rownames(result) <- "Delta method, analytic derivative"
library("nlWaldTest")
r <- nlConfint(obj = NULL, texts="b[2]/b[3]", level = 0.95, coeff = coef(m1),
Vcov = vcov(m1), df2 = TRUE, x = NULL)
result <- rbind(result, t(as.data.frame(c(Estimate=r[, 1], SE=NA, '2.5 %'=r[, 2], '97.5 %'=r[, 3]))))
rownames(result)[2] <- "Delta method, analytic derivative in nlWaldTest"
############# Now numerical derivative is used. The result is the same.
try_g <- function(...) {
par <- list(...)
return(par[[1]]/par[[2]])
}
r <- nlConfint2(texts="try_g(b[2], b[3])", level = 0.95, coeff = coef(m1),
Vcov = vcov(m1), df2 = TRUE)
result <- rbind(result, t(as.data.frame(c(Estimate=r[, 1], SE=NA, '2.5 %'=r[, 2], '97.5 %'=r[, 3]))))
rownames(result)[3] <- "Delta method, numeric derivative in nlWaldTest"
# Random numbers using only standard error
SE <- sqrt(diag(vcov(m1)))
out <- NULL
for (i in 1:100000) {
b <- coef(m1)
for (j in names(b)) b[j] <- rnorm(1, mean=b[j], sd=SE[j])
out <- c(out, try_g(b[2], b[3]))
}
r <- quantile(out, probs = c(0.5, 0.025, 0.975))
result <- rbind(result, t(as.data.frame(c(Estimate=unname(r[1]), SE=NA,
'2.5 %'=unname(r[2]),
'97.5 %'=unname(r[3])))))
rownames(result)[4] <- "Random numbers from SD, quantiles"
result <- rbind(result, t(as.data.frame(c(Estimate=mean(out), SE=sd(out),
'2.5 %'=mean(out)-qnorm(0.975)*sd(out),
'97.5 %'=mean(out)+qnorm(0.975)*sd(out)))))
rownames(result)[5] <- "Random numbers from SD, mean-sd"
# Random numbers using variance-Covariance matrix
library("MultiRNG")
dta <- draw.d.variate.normal(no.row=100000,d=3,mean.vec=coef(m1),cov.mat=vcov(m1))
out <- dta[, 2]/dta[, 3]
r <- quantile(out, probs = c(0.5, 0.025, 0.975))
result <- rbind(result, t(as.data.frame(c(Estimate=unname(r[1]), SE=NA,
'2.5 %'=unname(r[2]),
'97.5 %'=unname(r[3])))))
rownames(result)[6] <- "Random numbers from V-Cov, quantiles"
result <- rbind(result, t(as.data.frame(c(Estimate=mean(out), SE=sd(out),
'2.5 %'=mean(out)-qnorm(0.975)*sd(out),
'97.5 %'=mean(out)+qnorm(0.975)*sd(out)))))
rownames(result)[7] <- "Random numbers from V-Cov, mean-sd"
result
- Use delta method with or without analytic derivative, it does not change anything
- Do not use simple resampling using SD
- You can use resampling taking into variance-covariance matrix
library(car)
m1 <- lm(time ~ t1 + t2, data = Transact)
result <- deltaMethod(coef(m1), "t1/t2", vcov.=vcov(m1))
rownames(result) <- "Delta method, analytic derivative"
library("nlWaldTest")
r <- nlConfint(obj = NULL, texts="b[2]/b[3]", level = 0.95, coeff = coef(m1),
Vcov = vcov(m1), df2 = TRUE, x = NULL)
result <- rbind(result, t(as.data.frame(c(Estimate=r[, 1], SE=NA, '2.5 %'=r[, 2], '97.5 %'=r[, 3]))))
rownames(result)[2] <- "Delta method, analytic derivative in nlWaldTest"
############# Now numerical derivative is used. The result is the same.
try_g <- function(...) {
par <- list(...)
return(par[[1]]/par[[2]])
}
r <- nlConfint2(texts="try_g(b[2], b[3])", level = 0.95, coeff = coef(m1),
Vcov = vcov(m1), df2 = TRUE)
result <- rbind(result, t(as.data.frame(c(Estimate=r[, 1], SE=NA, '2.5 %'=r[, 2], '97.5 %'=r[, 3]))))
rownames(result)[3] <- "Delta method, numeric derivative in nlWaldTest"
# Random numbers using only standard error
SE <- sqrt(diag(vcov(m1)))
out <- NULL
for (i in 1:100000) {
b <- coef(m1)
for (j in names(b)) b[j] <- rnorm(1, mean=b[j], sd=SE[j])
out <- c(out, try_g(b[2], b[3]))
}
r <- quantile(out, probs = c(0.5, 0.025, 0.975))
result <- rbind(result, t(as.data.frame(c(Estimate=unname(r[1]), SE=NA,
'2.5 %'=unname(r[2]),
'97.5 %'=unname(r[3])))))
rownames(result)[4] <- "Random numbers from SD, quantiles"
result <- rbind(result, t(as.data.frame(c(Estimate=mean(out), SE=sd(out),
'2.5 %'=mean(out)-qnorm(0.975)*sd(out),
'97.5 %'=mean(out)+qnorm(0.975)*sd(out)))))
rownames(result)[5] <- "Random numbers from SD, mean-sd"
# Random numbers using variance-Covariance matrix
library("MultiRNG")
dta <- draw.d.variate.normal(no.row=100000,d=3,mean.vec=coef(m1),cov.mat=vcov(m1))
out <- dta[, 2]/dta[, 3]
r <- quantile(out, probs = c(0.5, 0.025, 0.975))
result <- rbind(result, t(as.data.frame(c(Estimate=unname(r[1]), SE=NA,
'2.5 %'=unname(r[2]),
'97.5 %'=unname(r[3])))))
rownames(result)[6] <- "Random numbers from V-Cov, quantiles"
result <- rbind(result, t(as.data.frame(c(Estimate=mean(out), SE=sd(out),
'2.5 %'=mean(out)-qnorm(0.975)*sd(out),
'97.5 %'=mean(out)+qnorm(0.975)*sd(out)))))
rownames(result)[7] <- "Random numbers from V-Cov, mean-sd"
result
Estimate SE 2.5 % 97.5 %
Delta method, analytic derivative 2.684653 0.3189858 2.059452 3.309853
Delta method, analytic derivative in nlWaldTest 2.684653 NA 2.059452 3.309853
Delta method, numeric derivative in nlWaldTest 2.684653 NA 2.059452 3.309853
Random numbers from SD, quantiles 2.685176 NA 2.223589 3.197951
Random numbers from SD, mean-sd 2.691127 0.2480579 2.204943 3.177312
Random numbers from V-Cov, quantiles 2.684422 NA 2.107294 3.368982
Random numbers from V-Cov, mean-sd 2.697886 0.3214745 2.067807 3.327964
Commentaires
Enregistrer un commentaire