Page 1 of 1
Bug in the Gamlj Plot method when using R
Posted: Thu Jul 04, 2024 6:40 pm
by Whirly123
I tend to use Gamlj in R and I usually extract the plot object like this:
plotObject <- plot(model)
However, this doesn't always work across the different models. For example it works in Gamlj 3 mixed models but not Gamlj 2 mixed models. It seems a bit inconsistent throughout, so I sometimes have to swap over.
The error I get is:
'descPlots' does not exist in this results element
I would hazard a guess that things aren't being named correctly as the plot object inside the model is actually called "mainPlots" not "descPlots" so the plot method won't work.
I hoped a work around would be to rename the object or copy it into something with the right name something like:
model$descPlots <- model$mainPlots
but that doesn't work as I get the error:
model$descPlots <- NA :
cannot add bindings to a locked environment
This now goes beyond my R knowledge. Help appreciated as I tend to rely on Galmj in R for almost everything and always need to edit the plots using ggplot.
Re: Bug in the Gamlj Plot method when using R
Posted: Thu Jul 04, 2024 7:06 pm
by Whirly123
I guess in addition how would I go about viewing the Gamlj code myself to see how ggplots were generated so I could potentially recreate some of it myself outside of gamlj with just an lmer or lm object? I tried ctrl clicking the gamljlm text but that doesn't quite send me to right place.
Re: Bug in the Gamlj Plot method when using R
Posted: Fri Jul 05, 2024 11:11 am
by mcfanda@gmail.com
Hi
it seems that the issue is due to the two versions being loaded at the same time. When you get the error "Error: 'descPlots' does not exist in this results element" is because `plot()` from gamlj 2 is applied to a GAMLj3 object. So, be sure that you load only the version you want to use.
Aside from the function plot() you can get the plot in gamlj version 2 as follows:
Code: Select all
mod1<-gamlj::gamljMixed(
formula = ycont~ 1 + x+( 1 | cluster ),
data = clustermanymodels,
plotHAxis = x)
myplot<-mod1$descPlot
and in GAMLj3
Code: Select all
mod1<-GAMLj3::gamlj_mixed(
formula = ycont~ 1 + x+( 1 | cluster ),
data = clustermanymodels,
plot_x = x,
ci_method = "wald")
myplot<-mod1$mainPlots
Please notice that version 2 is no longer maintained, so no update or bug fix will be done for it. GAMLj3 is the version that is constantly checked and updated
Re: Bug in the Gamlj Plot method when using R
Posted: Fri Jul 05, 2024 11:31 am
by Whirly123
Thanks for the help - there does still seem to be an issue with doing it this way:
myplot<-mod1$mainPlots
I can print the myplot object and it will print the plot but the object itself isn't a ggplot object in the the way using myplot <- plot(mod1) is.
So for example if I do something like :
myplot + theme_bw() it just returns NULL
Using the plot method returns a list (ggplot object) whereas mod1$mainPlots is an "object with active binding".
If I try to do this: plot(mod1$mainPlots) I get the error
Error: 'plot' does not exist in this results element
So none of that is really "extracting" the actually ggplot object for me.
Re: Bug in the Gamlj Plot method when using R
Posted: Sat Jul 06, 2024 10:02 am
by mcfanda@gmail.com
mod1$mainPlots contains an array of ggplot2 objects. This is because a model may need to produce more than one plot (think of a four-way interaction plot). Thus, to get the ggplot object you need to run
myplot<-mod1$mainPlots[[1]].
What plot() function does is to inspect $mainPlots, if it finds only one plot it returned as a ggplot2 object, if there are more than one plot it returns a list of ggplot2 objects. Thus, using plot() is recommended because it simplifies the returned object, but both methods work.
Re: Bug in the Gamlj Plot method when using R
Posted: Sat Jul 06, 2024 10:45 am
by Whirly123
Sorry I should have said in the previous post that I tried that too. The model only had one plot and yet I still extracted myplot<-mod1$mainPlots[[1]] because I figured it might be in an array.
Sadly, this still doesn't extract a ggplot object - it still prints a plot but still returns Null if I try to edit it as a ggplot (e.g. "myplot + theme_bw()" or whatever).
To make this easier to deal with I have made a reproducable example for you:
Code: Select all
library("tidyverse")
library("jmv")
library("GAMLj3")
data("selfesteem", package = "datarium")
longData <- pivot_longer(data = selfesteem,
cols = t1:t3,
names_to = "time")
longData$time <- as.factor(longData$time)
model <- GAMLj3::gamljlm(
formula = value ~ 1 +
time +
( 1 | id ),
data = longData,
plot_x = time,
plot_around='ci')
# this returns my lovely editable ggplot
methodPlot <- plot(model)
# and this works fine :)
methodPlot + theme_bw()
# this returns an "object containing active binding rather than a ggplot
extractedPlot <- model$mainPlots
# And so this returns NULL
extractedPlot + theme_bw()
# this also returns an "object containing active binding rather than a ggplot
extractedPlot <- model$mainPlots[[1]]
# And so this also returns NULL
extractedPlot + theme_bw()
I realise you have technically solved my problem since the plot method obviously now works fine but I would love to know what is happening here as it would increase my R knowledge (thanks in advance

!). And I love gamlj so being able wrangle more stuff out of it is useful. There is a ggplot object somewhere I should be able to extract it right (without the plot method)?
Re: Bug in the Gamlj Plot method when using R
Posted: Sat Jul 06, 2024 11:56 am
by mcfanda@gmail.com
sure. To dig into the gamlj object (as for any other complex object in R) my suggestion when exploring these functionalities is to use `class()` and `str()`, so we know what object are returned.
First, the recommended method
Code: Select all
methodPlot<-plot(model)
class(methodPlot)
[1] "gg" "ggplot"
so methodPlot is a ggplot object that can be manipulated with ggplot code.
accessing the plot from the gamlj object returns an array of jamovi Images, each Image has a function $plot$fun() that returns the ggplot object
Code: Select all
> class(extractPlot)
[1] "Array" "ResultsElement" "R6"
class(extractPlot[[1]])
[1] "Image" "ResultsElement" "R6"
one<-extractPlot[[1]]
class(one$plot$fun())
[1] "gg" "ggplot"
>
To be sure, here is a snippet from the plot() function that may interest you (other code in the function is not relevant here)
Code: Select all
plots <- list()
for (i in 1:length(object$mainPlots)) {
title <- object$mainPlots[[i]]$title
gplot <- object$mainPlots[[i]]$plot$fun() + ggplot2::ggtitle(title)
plots[[i]] <- gplot
}
if ("list" %in% class(plots) && length(plots) == 1)
plots <- plots[[1]]
plots
[code]
Re: Bug in the Gamlj Plot method when using R
Posted: Sat Jul 06, 2024 12:28 pm
by Whirly123
Amazing!
Thanks so much that was super useful!