Open mronkko opened 7 years ago
Hi Mikko,
Thanks for the suggestion! Sorry for the delay, but I have not had much time for programming in the past year (new daughter, job pressures, etc.). I would like to include this in the next version, and I think it can share a documentation page with compareFit()
. Does it still work with the latest development version of lavaan
?
It would help me out if you could add some roxygen2 comments to indicate which functions are imported that aren't in the base
package, as well as defining arguments that are not already part of compareFit()
. For example, you use is()
from the methods
package, which can be indicated with:
#' @import methods is
And to share the documentation page, you can use this comment before @export
:
#' @rdname compareFit
If you are unfamiliar with roxygen2, here is a good tutorial: http://r-pkgs.had.co.nz/man.html And you can see examples in my source code: https://github.com/simsem/semTools/blob/master/semTools/R/clipboard.R
If you need me to handle the documentation part, I don't think I would have time to do so before the next version goes to CRAN (hopefully end of April, if Yves can get lavaan out by then).
If you can add this to the https://github.com/simsem/semTools/blob/master/semTools/R/compareFit.R file and create a pull request, that works too. But you can also just post the source-code file here and I can add it myself. You can also add an @example
application for the help page to the https://github.com/simsem/semTools/blob/master/semTools/R/compareFit.R file, or I can add one myself.
Thanks!
Hi Terry,
I can relate to your situation because it is quite similar to mine ;) I will try to check this over the easter weekend or the week after easter.
I have experience using oxygen2 and can add documentation. I agree that the two functions should probably reside in the same file and share the documentation page. Also, I would like to refactor the code a bit because the function is very long and there is some duplicate code.
Would it make sense to have one function (e.g. compareModels) that compares coefficients and indices, and then just two wrappers (compareFit and compareEstimates) that call this one function to print just the coefficients or indices depending on which function is called?
Should I do this as a pull request?
Mikko
I would like to refactor the code a bit because the function is very long and there is some duplicate code.
Great!
Would it make sense to have one function (e.g. compareModels) that compares coefficients and indices, and then just two wrappers (compareFit and compareEstimates) that call this one function to print just the coefficients or indices depending on which function is called?
I don't think so. Then all the same work is being done, regardless of which wrapper is called. I like the 2 functions separate. But perhaps compareModels()
could be a wrapper that calls both compareFit()
and compareEstimates()
.
Should I do this as a pull request?
Yes, please -- whenever it is ready. That way I can see github's automatic check for conflicts with my current version.
Enjoy your holiday weekend! Terrence
This function will be a very useful companion to compareFit()
! I tried it myself and it worked very well. It can also serve as a pedagogical tool useful for students to see how parameter estimates change as the model specification changes.
May I suggest a few minor changes to compareEstimates()
?
Add
mod.names <- sapply(substitute(list(...))[-1], deparse)
to capture the names of the fit objects (as in compareFit()
) (expand the names if necessary if any of fit object is a list) and then store the names as an attribute to the output:
attr(PEframe, "mod.names") <- mod.names
print.CoefDiff()
can then retrieve these names
mod.names <- attr(x, "mod.names")
and add them as prefixes (or suffixes). E.g.,
colnames(m)[ colnames(m) == "est" ] <- paste0(mod.names, ":", "Estimate")
colnames(m)[ colnames(m) == "se" ] <- paste0(mod.names, ":", "Std.Err")
colnames(m)[ colnames(m) == "z" ] <- paste0(mod.names, ":", "z-value")
I tried these changes based on the version posted by @mronkko and this is the sample output:
Parameter Estimates:
Latent Variables:
fit1:Estimate fit2:Estimate
visual =~
x1 1.000 1.000
x2 0.554 0.527
x3 0.729 0.647
The following changes may also help to merge parameter estimates whether the models have more than one group (e.g., the measure invariance example in compareFit()
)
by_names <- c("lhs","op","rhs","exo")
if (any(sapply(PElist, function(x) "block" %in% colnames(x)))) {
by_names <- c(by_names, "block")
}
if (any(sapply(PElist, function(x) "group" %in% colnames(x)))) {
by_names <- c(by_names, "group")
}
PEframe <- join_all(PElist, by = by_names, match = "first")
I did not post here the modified code I tired because I am not sure whether the version in the first post of this issue is the latest version. (And I am also not the author so it may not be OK for me to modify the code directly.)
I look forward to seeing this function in semTools
.
P.S.: I am not familiar with join_all()
. It seems that the current version does not work when the two or more models are not nested, and some parameters are only in one model while some other parameters are only in another model. E.g.,
# textual =~ x8 only in A
HS.model.A <- ' visual =~ x1 + x2 + x3
textual =~ x4 + x5 + x6 + x8
speed =~ x7 + x8 + x9 '
# visual =~ x9 only in B
HS.model.B <- ' visual =~ x1 + x2 + x3 + x9
textual =~ x4 + x5 + x6
speed =~ x7 + x8 + x9 '
I tried type = "full"
but it only uses one copy of the columns in the ouput. The default, type = "left"
, will only include parameters in the first model, i.e., visual =~ x9
will be excluded if the fit of HS.model.B
is entered as the second object.
semTools currently includes function compareFit for comparing fit indices between multiple models. Users may also be interested in comparing coefficients across different models. I created a function for that. Please let me know whether you think that the following would be a useful addition to the package. Parts of the code have been copied from the compareFit function and the print function of the lavaan summary method.