grezniczek / redcap_field_shuffle

A REDCap External Module that puts fields into a random order
MIT License
0 stars 2 forks source link

Block-shuffling use case and solution #1

Open tobadia opened 1 year ago

tobadia commented 1 year ago

Hey @grezniczek !

Your module really helped heaps (we've discussed elsewhere already). Following having it in production on our instance, we got even more requests, including one interesting in need of "block-shuffling" : preserving some order (e.g. nested questions), but shuffling blocks of items.

I have come up with a solution that only uses your current script without any addition to the JS code. The use case here makes use of clever prefixing/suffixing of items and @CALCTEXT functions available in REDCap to identify a prefix (assumed to be structured identically across blocks), and append it with suffixes (no assumption on these although it makes life easier if they are similar). Within a given suffix, the prefixes have to appear in the same order.

Current solution That prefix is shuffled a first time (although with no corresponding items in instrument). On a subsequent instrument, the order obtained for these shuffled prefix is parsed with @CALCTEXT using find and mid functions to individually identify all the prefixes one by one. Each prefix is appended with the various suffixes using concat.

Other suggestions 1) Allow @SHUFFLE-FIELDS-xxx tags to be provided with an item instead of a lists of items to shuffle (e.g. @SHUFFLE-FIELDS-xxx="[calculated_before]") 2) Explicitely allow nesting with a dedicated syntax (to be thought, though, because looking at the current JS that's not so easy)

I'm attaching the XML of my demo project here. It builds upon yours, from this Git repo, so could be a nice addition (had to ZIP it, GitHub doesn't allow XML). FieldShuffleExternal_2022-12-14_1406.REDCap.xml.zip

grezniczek commented 1 year ago

This is quite impressive!

Block shuffling sounds interesting. I'll think about how to implement this.

Probably something like this: @SHUFFLE-FIELDS="(block_item_1,block_item_2),standalone_item_3,standalone_item_4,(block_item_5,block_item_6,block_item_7),standalone_item_8"

What would be a use case of the first suggestion (piping the field names)?

tobadia commented 1 year ago

Well the use case of the 1st suggestion was during my attempts at getting this working today. Thought it could come in handy, at some stage, but I may be overthinking it. I had in mind that providing it with a pre-populated field could be a way to let it know if was a pre-calculated order, that should not get randomized anymore, but rather used as actual map.

The actual blocking with proper syntax would be the proper way to address this. I like your suggestion, my initial thoughts involved something inspired by mixed-effect models in R, using a mixture of brackets, | and ,. But your solution makes more sense.

BTW I have slightly reduced the number of fields required in my example, by combining the second @CALCTEXT and @SHUFFLE-FIELDS-xxx action-tags into the same field. Happy to share if you want to include that somewhere as an example.