Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add glance methods and IV diagnostics #285

Merged
merged 30 commits into from
Feb 28, 2019
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
de8d78f
remove unnecessary items in summary list when no FEs
lukesonnet Jan 24, 2019
b9e7f0b
Add glance for lm_robust and some simple tests #282
lukesonnet Jan 24, 2019
78f61ad
Add diagnostics
lukesonnet Feb 3, 2019
70e673b
add glances and iv diagnostics
lukesonnet Feb 4, 2019
ec97123
proper weak instrument fstats; refactor fstats
lukesonnet Feb 6, 2019
cf70978
debug diagnostics; tests for simple HC0 and classical SEs working
lukesonnet Feb 6, 2019
79af875
Change default diagnostic to FALSE
lukesonnet Feb 6, 2019
37ba390
remove residuals and fix tests
lukesonnet Feb 7, 2019
1cbf941
fix overid test with robust ses; clean up iv diagnostic code
lukesonnet Feb 18, 2019
ecc0dad
progress on stata tests
lukesonnet Feb 18, 2019
b1a20d4
fix robust endogeneity test
lukesonnet Feb 19, 2019
534a3ac
set up diagnostics tests
lukesonnet Feb 19, 2019
e5bb199
finish basic testing
lukesonnet Feb 19, 2019
480a86b
broken paths
lukesonnet Feb 19, 2019
8cf3b13
Fix glance and tests
lukesonnet Feb 19, 2019
c029e17
glance.iv_robust test
lukesonnet Feb 19, 2019
0b25b17
HT glance
lukesonnet Feb 20, 2019
d8b0b06
fix testing
lukesonnet Feb 20, 2019
58847e1
print iv diagnostics if they exist
lukesonnet Feb 20, 2019
e5dde45
Finalize tests and exceptions for diagnostics
lukesonnet Feb 25, 2019
ee9da78
Add weights to docs
lukesonnet Feb 25, 2019
76724bc
Document diagnostic return value
lukesonnet Feb 25, 2019
95a3a66
Clean up glance
lukesonnet Feb 26, 2019
ea6c791
Clean up glance
lukesonnet Feb 26, 2019
afb9711
Clean up print
lukesonnet Feb 26, 2019
1d76100
Clean up dim
lukesonnet Feb 26, 2019
219d290
Add libgit2
lukesonnet Feb 26, 2019
b75b86e
fix exports
lukesonnet Feb 26, 2019
6fbc9c4
update description and news
lukesonnet Feb 27, 2019
2748c69
edit travis badge
lukesonnet Feb 27, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ update_repo.R
^tests/testthat/test-zzzbroom\.R$
^estimatr_.*\.tar\.gz$
^tests/testthat/test-texreg\.R$
^tests/testthat/test-gtsummary\.R$
^cran-comments\.md$

2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ addons:
r_github_packages:
- DeclareDesign/DDtools
- ropensci/git2r
- rstudio/gt
- vincentarelbundock/gtsummary

after_success:
- Rscript -e DDtools::after_build
Expand Down
5 changes: 5 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ S3method(confint,difference_in_means)
S3method(confint,horvitz_thompson)
S3method(confint,iv_robust)
S3method(confint,lm_robust)
S3method(glance,difference_in_means)
S3method(glance,iv_robust)
S3method(glance,lm_robust)
S3method(nobs,iv_robust)
S3method(nobs,lm_robust)
S3method(nobs,summary.lm_robust)
Expand Down Expand Up @@ -33,6 +36,7 @@ export(difference_in_means)
export(extract.iv_robust)
export(extract.lm_robust)
export(gen_pr_matrix_cluster)
export(glance)
export(horvitz_thompson)
export(iv_robust)
export(lm_lin)
Expand All @@ -43,6 +47,7 @@ export(starprep)
export(tidy)
importFrom(Formula,as.Formula)
importFrom(Rcpp,evalCpp)
importFrom(generics,glance)
importFrom(generics,tidy)
importFrom(methods,className)
importFrom(methods,isGeneric)
Expand Down
184 changes: 184 additions & 0 deletions R/S3_glance.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
#' @importFrom generics glance
#' @export
generics::glance

#' Glance at an estimatr object
#' @name estimatr_glancers
#' @templateVar class lm_robust
#' @return A data.frame with columns:
#' \item{r.squared}{the \eqn{R^2},
#' \deqn{R^2 = 1 - Sum(e[i]^2) / Sum((y[i] - y^*)^2),} where \eqn{y^*}
#' is the mean of \eqn{y[i]} if there is an intercept and zero otherwise,
#' and \eqn{e[i]} is the ith residual.}
#' \item{adj.r.squared}{the \eqn{R^2} but penalized for having more parameters, \code{rank}}
#' \item{se_type}{the standard error type specified by the user}
#' \item{statistic}{the value of the F-statistic}
#' \item{p.value}{p-value from the F test}
#' \item{df.residual}{residual degrees of freedom}
#' \item{N}{the number of observations used}
#'
#' @param x An object returned by one of the estimators
#' @param ... extra arguments (not used)
#'
#' @export
#' @family estimatr glancers
#' @seealso [generics::glance()], [estimatr::lm_robust()], [estimatr::lm_lin()]
#' @md
glance.lm_robust <- function(x, ...) {

if (length(x[["outcome"]]) > 1) {
stop("Cannot use `glance` on linear models with multiple responses.")
}

ret <- cbind(
data.frame(
r.squared = x[["r.squared"]],
adj.r.squared = x[["adj.r.squared"]]
),
if (exists("fstatistic", x)) {
data.frame(
statistic = x[["fstatistic"]][1],
p.value = pf(x[["fstatistic"]][1], x[["fstatistic"]][2], x[["fstatistic"]][3], lower.tail = FALSE)
)
} else {
data.frame(statistic = NA_real_, p.value = NA_real_)
},
data.frame(
df.residual = x[["df"]][1],
N = x[["N"]],
se_type = x[["se_type"]]
)
)

rownames(ret) <- NULL

as.data.frame(ret)
}

#' Glance at an estimatr object
#' @name estimatr_glancers
#' @templateVar class iv_robust
#' @return A data.frame with columns:
#' \item{r.squared}{The \eqn{R^2} of the second stage regression}
#' \item{adj.r.squared}{The \eqn{R^2} but penalized for having more parameters, \code{rank}}
#' \item{df.residual}{residual degrees of freedom}
#' \item{N}{the number of observations used}
#' \item{se_type}{the standard error type specified by the user}
#' \item{statistic}{the value of the F-statistic}
#' \item{p.value}{p-value from the F test}
#' \item{statistic.weakinst}{the value of the first stage F-statistic, useful for the weak instruments test}
#' \item{p.value.weakinst}{p-value from the first-stage F test, a test of weak instruments}
#'
#' @param x An object returned by one of the estimators
#' @param ... extra arguments (not used)
#'
#' @export
#' @family estimatr glancers
#' @seealso [generics::glance()], [estimatr::iv_robust()]
#' @md
glance.iv_robust <- function(x, ...) {

if (length(x[["outcome"]]) > 1) {
stop("Cannot use `glance` on linear models with multiple responses.")
}

ret <- cbind(
data.frame(
r.squared = x[["r.squared"]],
adj.r.squared = x[["adj.r.squared"]],
df.residual = x[["df.residual"]],
N = x[["N"]],
se_type = x[["se_type"]]
),
if (exists("fstatistic", x)) {
data.frame(
statistic = x[["fstatistic"]][1],
p.value = pf(x[["fstatistic"]][1], x[["fstatistic"]][2], x[["fstatistic"]][3], lower.tail = FALSE)
)
} else {
data.frame(statistic = NA_real_, p.value = NA_real_)
},
if (exists("diagnostic_firststage_fstatistic", x) && length(x[["diagnostic_firststage_fstatistic"]] == 4)) {
data.frame(
statistic.weakinst = x[["diagnostic_firststage_fstatistic"]]["value"],
p.value.weakinst = x[["diagnostic_firststage_fstatistic"]]["p.value"]
)
} else {
data.frame(statistic.weakinst = NA_real_, p.value.weakinst = NA_real_)
},
if (exists("diagnostic_endogeneity_fstatistic", x)) {
data.frame(
statistic.endogeneity = x[["diagnostic_endogeneity_fstatistic"]]["value"],
p.value.endogeneity = x[["diagnostic_endogeneity_fstatistic"]]["p.value"]
)
} else {
data.frame(statistic.endogeneity = NA_real_, p.value.endogeneity = NA_real_)
},
if (exists("diagnostic_overid_fstatistic", x)) {
data.frame(
statistic.overid = x[["diagnostic_overid_fstatistic"]]["value"],
p.value.overid = x[["diagnostic_overid_fstatistic"]]["p.value"]
)
} else {
data.frame(statistic.overid = NA_real_, p.value.overid = NA_real_)
}
)

as.data.frame(ret)
}

#' Glance at an estimatr object
#' @name estimatr_glancers
#' @templateVar class difference_in_means
#' @return A data.frame with columns:
#' \item{r.squared}{The \eqn{R^2} of the second stage regression}
#' \item{adj.r.squared}{The \eqn{R^2} but penalized for having more parameters, \code{rank}}
#' \item{df.residual}{residual degrees of freedom}
#' \item{N}{the number of observations used}
#' \item{statistic}{the value of the F-statistic}
#' \item{p.value}{p-value from the F test}
#' \item{statistic.weakinst}{the value of the first stage F-statistic, useful for the weak instruments test}
#' \item{p.value.weakinst}{p-value from the first-stage F test, a test of weak instruments}
#'
#' @param x An object returned by one of the estimators
#' @param ... extra arguments (not used)
#'
#' @export
#' @family estimatr glancers
#' @seealso [generics::glance()], [estimatr::difference_in_means()]
#' @md
glance.difference_in_means <- function(x, ...) {
ret <- cbind(
data.frame(
design = x[["design"]],
df = x[["df"]],
N = x[["N"]]
),
if (exists("N_blocks", x)) {
data.frame(N_blocks = x[["N_blocks"]])
} else {
data.frame(N_blocks = NA_real_)
},
if (exists("N_clusters", x)) {
data.frame(N_clusters = x[["N_clusters"]])
} else {
data.frame(N_clusters = NA_real_)
}
)

as.data.frame(ret)
}


#' @export
#' @family estimatr glancers
#' @seealso [generics::glance()], [estimatr::horvitz_thompson()]
#' @md
glance.horvitz_thompson <- function(x, ...) {
ret <- data.frame(
N = x[["N"]]
)
# TODO: add standard error type

as.data.frame(ret)
}
2 changes: 1 addition & 1 deletion R/S3_print.R
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ print_summary_lm_like <- function(x,
fstat
)

if (!is.null(x$proj_fstatistic)) {
if (exists("proj_fstatistic", x)) {
cat(
"\nMultiple R-squared (proj. model): ",
formatC(x$proj_r.squared, digits = digits),
Expand Down
38 changes: 23 additions & 15 deletions R/S3_summary.R
Original file line number Diff line number Diff line change
Expand Up @@ -57,23 +57,31 @@ summary.iv_robust <- function(object, ...) {


summary_lm_model <- function(object) {
return_list <-
object[c(
"call",
"k",
"rank",
"df.residual",
"r.squared",
"adj.r.squared",
"fstatistic",

out_values <- c(
"call",
"k",
"rank",
"df.residual",
"res_var",
"weighted",
"se_type",
"fes",
"r.squared",
"adj.r.squared",
"fstatistic"
)
# Different returns if fixed effects in the output
if (object[["fes"]]) {
out_values <- c(
out_values,
"proj_r.squared",
"proj_adj.r.squared",
"proj_fstatistic",
"res_var",
"weighted",
"se_type",
"fes"
)]
"proj_fstatistic"
)
}

return_list <- object[out_values]

# Split into two lists if multivariate linear model

Expand Down
Loading