3

I am comparing lavaan objects using semTools::compareFit. It is throwing a very strange error message.

I tried also the following reproducible example:

data("HolzingerSwineford1939",package="lavaan")
HS.modelA <- ' visual  =~ x1 + x2 + x3
              textual =~ x4 + x5 + x6
              speed   =~ x7 + x8 + x9'

HS.modelB<- ' visual  =~ x1 + x2
              textual =~ x4 + x5 + x6
              speed   =~ x7 + x8 + x9'
fit.A<- cfa(HS.modelA, data = HolzingerSwineford1939)
fit.B<- cfa(HS.modelB, data = HolzingerSwineford1939)
semTools::compareFit(fit.A,fit.B)

It returns:

Error in getMethod("summary", signature = "FitDiff") : no method found for function 'summary' and signature FitDiff

Also, as the code is inside a function, but I would like to see the output printed in the screen, I also included:

result<-semTools::compareFit(fit.A,fit.B)
semTools::saveFile(result, file="",what="summary", tableFormat=FALSE)

This returns

Length Class Mode

  1 FitDiff      S4

I see the mention in the first error message something related to summary and methods... I have some S3 summary methods, trying to formalize in a package for personal use... not sure if it is related... is it possible I have messed up something? It is happening in more than one project in a RStudio installation... I have the impression it worked before...

I appreciate any help.

hamagust
  • 728
  • 2
  • 10
  • 28
  • your code works perfectly to me. Probably you have another package that is currently overwriting the function summary (I guess it's your package for personal use).. Try to restart R by pressing: Crtl + Shift + F10. You will detach all libraries. – Edo Jul 25 '20 at 01:34
  • I am having the exact same problem. Any ideas on how to solve this? – JPMD Aug 03 '20 at 22:51
  • not exactly, @JPMD... I started to believe it has really something with the S3 method specification... when I reinstalled (not just re-load) the semTools package, it worked again for a while... even using that new summary methods I was coding... but it comes back later... – hamagust Aug 06 '20 at 01:24
  • @JPMD, I have included the code of how I circumvented the problem. That's not possibly an ideal solution, as does not solve the issue for all s4 methods, but it enabled me a solution for the specific problem... – hamagust Aug 26 '20 at 19:39
  • Thanls @hamagust. That works for delta chi-square. How can we make it work for Delta CFI, Delta RMSEA, etc? – JPMD Oct 15 '20 at 08:51
  • Hi @JPMD, you mean testing significance on the differences on other fit measures? The only statistical test is for chi-square. So, semtool shows just the test for chi-square... The other fit measures are shown in a table for each of the models tested, but without significance test. – hamagust Oct 15 '20 at 21:02
  • Hi @hamagust. Yes, I know you only get p-values for the delta chisquare test. But I was not getting the Delta CFI, RMSEA,... in the full table (It was a parametrization in the output from RStudio). Thanks! – JPMD Oct 16 '20 at 10:16
  • I can't help but notice that your reprex uses lazy loading (`semTools::compareFit()`) rather than loading the `library(semTools)`. This could prevent R finding the methods defined in semTools after the `FitDiff-class` object is created. But I am aware that issues like this still occur when semTools is loaded correctly (e.g., it frequently happens with `lavaan.mi-class` objects). – Terrence Dec 02 '22 at 10:17

2 Answers2

2

I am reporting here how I circumvented the problem.

The conclusion of what is happening here:

This is really an issue with S3 methods messing up the S4 method dispatch.

If I load showMethods(summary) before loading the semTools package, I get:

Function "summary":
 <not an S4 generic function>)

But if I load showMethods(summary) after loading it, I get:

Function: summary (package base)
object="ANY"
object="FitDiff"
    (inherited from: object="ANY")
object="lavaan"
object="lavaanList"
object="mle"

So, the solution:

Considering the FitDiff object structure, I created a summary.FitDiff (s3 method):

summary.FitDiff<-function(object){
          print(object@nested)
          return(object@fit)
}

and this summary method is used with the FitDiff object:

a<-semTools::compareFit(fit.A,fit.B)
summary(a)

This is not a perfect solution, the ideal solution should involve something with how to specify s3 methods without messing up all possible s4method, but I have not sufficient knowledge about s4 methods... It solved my problem for now...

hamagust
  • 728
  • 2
  • 10
  • 28
  • I was having the same issue and your solution solved it. I'm not sure I quite understand what's happening, though. Also, the problem started appearing fairly recently. Any thoughts on how to solve this issue more permanently? – msoftrain Dec 16 '20 at 14:53
  • Hi @msoftrain, not yet... I am also very confused... my hypotheses is about S3 summary method messing up with something in SemTools's S4 function... But my knowledge about S4 functions are still really limited... If this is true, any package can mess up this function... as I believe S3 summary function is usual in several packages... – hamagust Dec 16 '20 at 16:25
  • 1
    Sorry I never saw this OP. I also find S4 method dispatch issues elusive. I was advised not to "mix" S3 and S4, e.g., defining an S3 `summary()` method for an S4-class object. Feel free to include this in your script, but I need to find another solution for semTools source code. – Terrence Dec 02 '22 at 10:14
  • Dear @Terrence, thank you for taking time to look at my question. Honoured to see your message here... I understand you are the maintainer of semTools and co-author of Lavaan package, thank you so much for the relevant packages. – hamagust Dec 02 '22 at 17:08
1

I just experienced the same issue. Yesterday, I used the semTools::measEq.syntax to generate models for the measurement invariance. Then I used the compareFit() function with summary() and I was able to see the output in the console. This morning, I ran the script again, and receive this output in the console

Length Class Mode
1 FitDiff      S4

Following @hamagust observation, I uninstalled semTools pacakage, reinstalled it and ran the script again. This time it works. Checking the showMethods(summary) revealed this.

Function: summary (package base)
object="FitDiff"
object="lavaan"
object="lavaan.mi"
object="lavaanList"
object="measEq.syntax"
object="mle"
object="Net"
object="permuteMeasEq"
object="sparseMatrix"
object="stanfit"
object="twostage"

The object is "FitDiff" and not inherited from: object="ANY" as OP presented. I wonder if next week I will have to do the same manipulation...