gen_userp {semlbci} | R Documentation |
Create a Wrapper To Be Used in 'lavaan' Models
Description
Make a function on
lavaan
object usable in a lavaan
model syntax.
Usage
gen_userp(func, sem_out)
gen_sem_out_userp(
userp,
sem_out,
userp_name = "semlbciuserp1234",
fix = TRUE,
control_args = list(),
iter.max = 10000,
max_attempts = 5
)
Arguments
func |
A function that receives a
|
sem_out |
A |
userp |
A function that is
generated by |
userp_name |
The name of the
function |
fix |
If |
control_args |
To be passed to
the argument of the same name in
|
iter.max |
The maximum number of iteration when the generated function fit the model. Default is 10000. |
max_attempts |
If the initial fit with the equality constraint fails, how many more attempts will be made by the generated function. Default is 5. |
Details
gen_userp
There are cases in which we want to
create a user parameter which is a
function of other free parameters,
computed by a function. However such
a function may work only on a
lavaan
object.
If the target function works by
extracting parameter estimates stored
in the Model
slot and/or the
implied
slot, then gen_userp()
can be used to convert it to a
function that retrieves the parameter
estimates when being called by
lavaan::lavaan()
or its wrappers,
modifies the stored
lavaan
object using
lavaan::lav_model_set_parameters()
and lavaan::lav_model_implied()
to
change the estimates, and call the
target function.
Note that this is an unconventional way to define a user parameter and the generated function should always be checked to see whether it works as expected.
As shown in the examples, the parameter computed this may not have standard error nor p-value.
The main purpose is for the point
estimate, for searching the
likelihood-based confidence bound
using ci_bound_ur()
and
ci_bound_ur_i()
.
Note that the target function
specified in func
should work
directly on the parameter estimates
stored in the Model
slot and then
get the estimates using
lavaan::lav_model_get_parameters()
.
Functions that work on the unmodified
output generated by
lavaan::lavaan()
usually do not
work.
Users are not recommended to use
gen_userp()
and gen_sem_out_userp()
directly because they require
unconventional way to extract
parameter estimates from a lavaan
model. However, developers may use
them to include functions
they wrote in a lavaan model. This
is the technique used by
ci_bound_ur_i()
to constrain any
parameter in a model to an arbitrary
value.
gen_sem_out_userp
The function gen_sem_out_userp()
is to be used internally
for generating a function for searching
a likelihood-based confidence bound.
It is exported because it needs to
be run in an fresh external R process,
usually created by callr
in other
internal functions.
Value
gen_userp
It returns a function that
accepts a numeric vector of length
equals to the number of free parameters
in sem_out
, and returns a scalar
which is the output of func
. If this
vector is not supplied, it will try to
find it in the parent.frame()
. This
is how it works inside a lavaan
model.
gen_sem_out_userp
If fix
is TRUE
, it returns a
function with these arguments:
-
target
: The value to which the user-defined parameter will be fixed to. -
verbose
: IfTRUE
, additional information will be printed when fitting the model. -
control
: The values to be passed as a list to the argument of the same name inlavaan::lavaan()
. -
seed
: Numeric. If supplied, it will be used inset.seed()
to initialize the random number generator. Necessary to reproduce some results because random numbers are used in some steps inlavaan
. IfNULL
, the default,set.seed()
will not be called.
If fix
is 'FALSE, then it returns a
function with optional arguments that
will be ignored, Calling it will
simply fit the modified model to the
data. Useful for getting the value of
the user-defined parameter.
Examples
library(lavaan)
data(simple_med)
dat <- simple_med
mod <-
"
m ~ a*x
y ~ b*m
ab := a*b
"
fit_med <- sem(mod, simple_med, fixed.x = FALSE)
parameterEstimates(fit_med)
# A trivial example for verifying the results
my_ab <- function(object) {
# Need to use lav_model_get_parameters()
# because the object is only a modified
# lavaan-object, not one directly
# generated by lavaan function
est <- lavaan::lav_model_get_parameters(object@Model, type = "user")
unname(est[1] * est[2])
}
# Check the function
my_ab(fit_med)
coef(fit_med, type = "user")["ab"]
# Create the function
my_userp <- gen_userp(func = my_ab,
sem_out = fit_med)
# Try it on the vector of free parameters
my_userp(coef(fit_med))
# Generate a modified lavaan model
fit_userp <- gen_sem_out_userp(userp = my_userp,
userp_name = "my_userp",
sem_out = fit_med)
# This function can then be used in the model syntax.
# Note that the following example only work when called inside the
# workspace or inside other functions such as ci_bound_ur()`
# and `ci_bound_ur_i()` because `lavaan::sem()` will
# search `my_userp()` in the global environment.
# Therefore, the following lines are commented out.
# They should be run only in a "TRUE" interactive
# session.
# mod2 <-
# "
# m ~ x
# y ~ m
# ab := my_userp()
# "
# fit_med2 <- sem(mod2, simple_med, fixed.x = FALSE)
# parameterEstimates(fit_med2)
#
# # Fit the model with the output of the function, a*b
# # fixed to .50
#
# fit_new <- fit_userp(.50)
#
# # Check if the parameter ab is fixed to .50
# parameterEstimates(fit_new)