@@ -374,3 +374,145 @@ values do not match.
374374"""
375375param_values (partable:: ParameterTable , col:: Symbol = :estimate ) =
376376 param_values! (fill (NaN , nparams (partable)), partable, col)
377+
378+ """
379+ lavaan_param_values!(out::AbstractVector, partable_lav,
380+ partable::ParameterTable,
381+ lav_col::Symbol = :est, lav_group = nothing)
382+
383+ Extract parameter values from the `partable_lav` lavaan model that
384+ match the parameters of `partable` into the `out` vector.
385+
386+ The method sets the *i*-th element of the `out` vector to
387+ the value of *i*-th parameter from `params(partable)`.
388+
389+ Note that the lavaan and `partable` models are matched by the
390+ the names of variables in the tables (`from` and `to` columns)
391+ as well as the type of their relationship (`relation` column),
392+ and not by the names of the model parameters.
393+ """
394+ function lavaan_param_values! (
395+ out:: AbstractVector ,
396+ partable_lav,
397+ partable:: ParameterTable ,
398+ lav_col:: Symbol = :est ,
399+ lav_group = nothing ,
400+ )
401+
402+ # find indices of all df row where f is true
403+ findallrows (f:: Function , df) = findall (f (r) for r in eachrow (df))
404+
405+ (length (out) == nparams (partable)) || throw (
406+ DimensionMismatch (
407+ " The length of parameter values vector ($(length (out)) ) does not match the number of parameters ($(nparams (partable)) )" ,
408+ ),
409+ )
410+ partable_mask = findall (partable. columns[:free ])
411+ param_index = Dict (param => i for (i, param) in enumerate (params (partable)))
412+
413+ lav_values = partable_lav[:, lav_col]
414+ for (from, to, type, id) in zip (
415+ [
416+ view (partable. columns[k], partable_mask) for
417+ k in [:from , :to , :parameter_type , :param ]
418+ ]. .. ,
419+ )
420+ lav_ind = nothing
421+
422+ if from == Symbol (" 1" )
423+ lav_ind = findallrows (
424+ r ->
425+ r[:lhs ] == String (to) &&
426+ r[:op ] == " ~1" &&
427+ (isnothing (lav_group) || r[:group ] == lav_group),
428+ partable_lav,
429+ )
430+ else
431+ if type == :↔
432+ lav_type = " ~~"
433+ elseif type == :→
434+ if (from ∈ partable. latent_vars) && (to ∈ partable. observed_vars)
435+ lav_type = " =~"
436+ else
437+ lav_type = " ~"
438+ from, to = to, from
439+ end
440+ end
441+
442+ if lav_type == " ~~"
443+ lav_ind = findallrows (
444+ r ->
445+ (
446+ (r[:lhs ] == String (from) && r[:rhs ] == String (to)) ||
447+ (r[:lhs ] == String (to) && r[:rhs ] == String (from))
448+ ) &&
449+ r[:op ] == lav_type &&
450+ (isnothing (lav_group) || r[:group ] == lav_group),
451+ partable_lav,
452+ )
453+ else
454+ lav_ind = findallrows (
455+ r ->
456+ r[:lhs ] == String (from) &&
457+ r[:rhs ] == String (to) &&
458+ r[:op ] == lav_type &&
459+ (isnothing (lav_group) || r[:group ] == lav_group),
460+ partable_lav,
461+ )
462+ end
463+ end
464+
465+ if length (lav_ind) == 0
466+ throw (
467+ ErrorException (
468+ " Parameter $id ($from $type $to ) could not be found in the lavaan solution" ,
469+ ),
470+ )
471+ elseif length (lav_ind) > 1
472+ throw (
473+ ErrorException (
474+ " At least one parameter was found twice in the lavaan solution" ,
475+ ),
476+ )
477+ end
478+
479+ param_ind = param_index[id]
480+ param_val = lav_values[lav_ind[1 ]]
481+ if isnan (out[param_ind])
482+ out[param_ind] = param_val
483+ else
484+ @assert out[param_ind] ≈ param_val atol = 1E-10 " Parameter :$id value at row #$lav_ind ($param_val ) differs from the earlier encountered value ($(out[param_ind]) )"
485+ end
486+ end
487+
488+ return out
489+ end
490+
491+ """
492+ lavaan_param_values(partable_lav, partable::ParameterTable,
493+ lav_col::Symbol = :est, lav_group = nothing)
494+
495+ Extract parameter values from the `partable_lav` lavaan model that
496+ match the parameters of `partable`.
497+
498+ The `out` vector should be of `nparams(partable)` length.
499+ The *i*-th element of the `out` vector will contain the
500+ value of the *i*-th parameter from `params(partable)`.
501+
502+ Note that the lavaan and `partable` models are matched by the
503+ the names of variables in the tables (`from` and `to` columns),
504+ and the type of their relationship (`relation` column),
505+ but not by the ids of the model parameters.
506+ """
507+ lavaan_param_values (
508+ partable_lav,
509+ partable:: ParameterTable ,
510+ lav_col:: Symbol = :est ,
511+ lav_group = nothing ,
512+ ) = lavaan_param_values! (
513+ fill (NaN , nparams (partable)),
514+ partable_lav,
515+ partable,
516+ lav_col,
517+ lav_group,
518+ )
0 commit comments