Skip to content

Commit 5dd41a9

Browse files
committed
[IV estimation] iv.samplestats = TRUE triggers 2SLS based on sample statistics only
1 parent 705dff4 commit 5dd41a9

File tree

4 files changed

+474
-49
lines changed

4 files changed

+474
-49
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: lavaan
22
Title: Latent Variable Analysis
3-
Version: 0.6-22.2505
3+
Version: 0.6-22.2506
44
Authors@R: c(person(given = "Yves", family = "Rosseel",
55
role = c("aut", "cre"),
66
email = "Yves.Rosseel@UGent.be",

R/lav_object_inspect.R

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,17 @@ lav_lavaan_lavinspect <- function(object, # nolin
626626
add.labels = add.labels, add.class = add.class,
627627
drop.list.single.group = drop.list.single.group)
628628

629+
# instrumental variables
630+
} else if(what %in% c("iv", "ivs", "miiv", "miivs", "instr", "instruments")) {
631+
lav_object_inspect_iv(object,
632+
drop.list.single.group = drop.list.single.group)
633+
} else if(what %in% c("eqs")) {
634+
lav_object_inspect_eqs(object,
635+
drop.list.single.group = drop.list.single.group)
636+
} else if(what %in% c("sargan")) {
637+
lav_object_inspect_sargan(object,
638+
drop.list.single.group = drop.list.single.group)
639+
629640
# post-checking
630641
} else if (what == "post.check" || what == "post") {
631642
lav_object_post_check(object)
@@ -3323,3 +3334,129 @@ lav_object_inspect_ntotal <- function(object) {
33233334
N
33243335
}
33253336

3337+
lav_object_inspect_iv <- function(object, drop.list.single.group = FALSE) {
3338+
3339+
if (is.null(object@internal$eqs)) {
3340+
lav_msg_stop(gettext("no equations/ivs found"))
3341+
}
3342+
lavmodel <- object@Model
3343+
lavdata <- object@Data
3344+
3345+
# grab equations
3346+
iv_list <- object@internal$eqs
3347+
3348+
# nblocks
3349+
nblocks <- object@pta$nblocks
3350+
3351+
table <- vector("list", length = nblocks)
3352+
for (b in seq_len(nblocks)) {
3353+
eqs <- iv_list[[b]]
3354+
lhs <- sapply(eqs, "[[", "lhs")
3355+
rhs <- sapply(lapply(eqs, "[[", "rhs"), paste, collapse = " + ")
3356+
lhs_new <- sapply(eqs, "[[", "lhs_new")
3357+
rhs_new <- sapply(lapply(eqs, "[[", "rhs_new"), paste, collapse = " + ")
3358+
miiv <- sapply(lapply(eqs, "[[", "miiv"), paste, collapse = ", ")
3359+
table[[b]] <- data.frame(
3360+
lhs = lhs, rhs = rhs,
3361+
lhs.new = lhs_new, rhs.new = rhs_new, instruments = miiv
3362+
)
3363+
class(table[[b]]) <- c("lavaan.data.frame", "data.frame")
3364+
}
3365+
3366+
# return value
3367+
return.value <- table
3368+
3369+
# drop list?
3370+
if (lavmodel@ngroups == 1L && drop.list.single.group) {
3371+
return.value <- return.value[[1]]
3372+
} else if (!is.null(lavdata)) {
3373+
if (length(lavdata@group.label) > 0L) {
3374+
names(return.value) <- unlist(lavdata@group.label)
3375+
}
3376+
}
3377+
3378+
return.value
3379+
}
3380+
3381+
lav_object_inspect_eqs <- function(object, drop.list.single.group = FALSE) {
3382+
3383+
if (is.null(object@internal$eqs)) {
3384+
lav_msg_stop(gettext("no equations/ivs found"))
3385+
}
3386+
lavmodel <- object@Model
3387+
lavdata <- object@Data
3388+
3389+
# grab equations
3390+
eqs <- object@internal$eqs
3391+
3392+
# return value
3393+
return.value <- eqs
3394+
3395+
# drop list?
3396+
if (lavmodel@ngroups == 1L && drop.list.single.group) {
3397+
return.value <- return.value[[1]]
3398+
} else if (!is.null(lavdata)) {
3399+
if (length(lavdata@group.label) > 0L) {
3400+
names(return.value) <- unlist(lavdata@group.label)
3401+
}
3402+
}
3403+
3404+
return.value
3405+
}
3406+
3407+
lav_object_inspect_sargan <- function(object, drop.list.single.group = FALSE) {
3408+
3409+
if (is.null(object@internal$eqs)) {
3410+
lav_msg_stop(gettext("no equations/ivs found"))
3411+
}
3412+
lavmodel <- object@Model
3413+
lavdata <- object@Data
3414+
3415+
# grab equations
3416+
iv_list <- object@internal$eqs
3417+
3418+
# nblocks
3419+
nblocks <- object@pta$nblocks
3420+
3421+
table <- vector("list", length = nblocks)
3422+
for (b in seq_len(nblocks)) {
3423+
eqs <- iv_list[[b]]
3424+
lhs <- sapply(eqs, "[[", "lhs")
3425+
rhs <- sapply(lapply(eqs, "[[", "rhs"), paste, collapse = " + ")
3426+
miiv <- sapply(lapply(eqs, "[[", "miiv"), paste, collapse = ", ")
3427+
sargan.stat <- sapply(seq_along(eqs),
3428+
function(x) eqs[[x]][["sargan"]]["stat"])
3429+
sargan.df <- sapply(seq_along(eqs),
3430+
function(x) eqs[[x]][["sargan"]]["df"])
3431+
sargan.pvalue <- sapply(seq_along(eqs),
3432+
function(x) eqs[[x]][["sargan"]]["pvalue"])
3433+
table[[b]] <- data.frame(
3434+
lhs = lhs, rhs = rhs, instruments = miiv,
3435+
sargan.stat = sargan.stat, df = sargan.df, pvalue = sargan.pvalue
3436+
)
3437+
3438+
# remove rows for which the Sargan statistic is NA
3439+
na.idx <- which(is.na(sargan.stat))
3440+
if (length(na.idx) > 0L) {
3441+
table[[b]] <- table[[b]][-na.idx, , drop = FALSE]
3442+
}
3443+
3444+
class(table[[b]]) <- c("lavaan.data.frame", "data.frame")
3445+
}
3446+
3447+
# return value
3448+
return.value <- table
3449+
3450+
# drop list?
3451+
if (lavmodel@ngroups == 1L && drop.list.single.group) {
3452+
return.value <- return.value[[1]]
3453+
} else if (!is.null(lavdata)) {
3454+
if (length(lavdata@group.label) > 0L) {
3455+
names(return.value) <- unlist(lavdata@group.label)
3456+
}
3457+
}
3458+
3459+
return.value
3460+
}
3461+
3462+

R/lav_options_estimator.R

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,7 @@ lav_options_est_iv <- function(opt) {
598598
if (is.null(opt$estimator.args)) {
599599
# create default list
600600
opt$estimator.args <- list(iv.method = "2SLS",
601+
iv.samplestats = FALSE,
601602
iv.varcov.method = "RLS",
602603
iv.varcov.se = TRUE,
603604
iv.varcov.modelbased = TRUE)
@@ -607,6 +608,12 @@ lav_options_est_iv <- function(opt) {
607608
} else if (!opt$estimator.args$iv.method %in% "2SLS") {
608609
lav_msg_stop(gettext("iv.method should be 2SLS (for now)."))
609610
}
611+
if (is.null(opt$estimator.args$iv.samplestats)) {
612+
opt$estimator.args$iv.samplestats <- FALSE
613+
}
614+
if (opt$.categorical) {
615+
opt$estimator.args$iv.samplestats <- TRUE
616+
}
610617
if (is.null(opt$estimator.args$iv.varcov.method)) {
611618
opt$estimator.args$iv.varcov.method <- "RLS"
612619
} else if (!opt$estimator.args$iv.varcov.method %in%

0 commit comments

Comments
 (0)