Chapter 8 Smart Tables Update
8.1 The issue
The COOLj
module we are building is pretty fast, so we can update its options and still get a smooth feeling from the output section. Indeed, if we are using the Big 5
data with 4 covariates
, we can flag and unflag the Show means for Sig.
or ES CI
options and get the results very quickly.
Imagine now that your module gets quite complex, with tens of tables and options. Likely, some of the table will require some time to update (maybe one uses bootstrap, for instance), and that will slow down the display of all other tables. Let’s simulate that by artificially slowing down our (original) anova
tables.
#...#
=function() {
run_main_anova
<- as.data.frame(car::Anova(self$model,type=3))
.anova names(.anova) <- c("nothing","df1","test","p")
$df2 <- self$model$df.residual
.anova$var <- rownames(.anova)
.anovaSys.sleep(3) ## simulate a slow computation
return(.anova)
},#...#
If you try now, you’ll see that every time the user changes something in the GUI, they have to wait for all tables to be filled. This behavior can be changed.
8.2 The Solution
Many tables do not need to be re-run every time an option is changed. Our anova
table, for instance, does not need to be re-computed when we ask for the means, by flagging the Show means for sig.
option. The two tables are independent, so showing one should not affect showing the other.
By default, all jamovi tables are initialized and run every time the input GUI changed. We can change this behavior by adding the property clearWith:
to the tables in .r.yaml
file. In clearWith:
, one can specify the options that would update the table. All changes in other options will not update the table. Thus, in our example, we can set .r.yaml
file as follows:
# ... ##
- name: anova
title: ANOVA table
type: Table
## Here is the new property
clearWith:
- dep
- covs
columns:
- name: var
title: "Variable"
type: text
## ... ##
Then we need to init the table, with some simple information like this:
#...#
=function() {
init_main_anova
<- self$analysis$options$covs
covs <- c("(Intercept)",covs,"Residuals")
terms <- lapply(terms, function(x) list(var=x))
tab return(tab)
},# the run function did not change
=function() {
run_main_anova
<- as.data.frame(car::Anova(self$model,type=3))
.anova names(.anova) <- c("nothing","df1","test","p")
$df2 <- self$model$df.residual
.anova$var <- rownames(.anova)
.anovaSys.sleep(3) ## simulate a slow computation
return(.anova)
},#...#
If you now compile the module and flag and the unflag the Show Means for Sig.
option, you’ll see that the anova
table do not change and the execution becomes much faster. If you chance the dependent variable or some of the covariates, the two tables will update.
If you do this process for all the tables, you will see that they update only when needed. The only exception are Unkeyed Arrays of tables (the ones you defined based on the results, such as the sig_means
array in the example). They are always refilled, because jamovi cannot know in advanced how many tables you need.
8.3 Bottom line
One can program jamovi modules freely with all techniques one wishes. If one wants to take advantage of jamovi flexibility and jmvScaffold
helping function, one can follow these guidelines:
- Define a table in
.r.yaml
- Define a
Scaffold
runner - Associate each table in the
.b.R
file to a SmartTable or Smart Array - Write a
init_tablename
in theRunner
object to initialize the table - Write a
run_tablename
in theRunner
object to fill the table - Adjust the aestetics of the table in the
.b.R
file