Each of the models and analyses is only able to run because mocapGrip
has metadata about what to do. There is a large amount of default information included in mocapGrip (this is stored in the modelMetadata
object by default), but this can be replaced with your own model metadata. The rest of this vignette will describe how to do that, and what structure you need to have to do that.
The model metadata is read into mocapGrip
from a specially formatted json file. These files take the same format as the default file that comes with the package. The basic structure of this file (although with only the action maximum grip dataSet and using the predictor variable for stick (as continuous)) looks like:
{ "variableExplanations" : { "stickcmScaled" : "the size of the stick in centimeters (centered at 8 cm, where 1 unit difference is 1 cm difference in stick size)", "fins" : "the configuration of the fins (closed, none, open; where closed is the reference level)", "stickcmScaledXfins" : "the interaction between the size of the stick and configuration of fins", "maxGrip" : "maximum grip aperture (in mm)", "obsisSubj" : "by subject" }, "models" : { "analyses" : { "maxGrip.stickAsContinuous" : { "variablesToUse" : { "outcome" : "maxGrip", "predictor1" : "stickcmScaled", "predictor2" : "fins", "grouping1" : "obsisSubj" } } }, "modelStructures" : { "interactionInPredAndGroup" : "paste0(outcome, '~', predictor1, '*', predictor2, '+', '(', '1+', predictor1, '*', predictor2, '|', grouping1, ')')", "interactionInPred" : "paste0(outcome, '~', predictor1, '*', predictor2, '+', '(', '1+', predictor1, '+', predictor2, '|', grouping1, ')')", "noInteraction" : "paste0(outcome, '~', predictor1, '+', predictor2, '+', '(', '1+', predictor1, '+', predictor2, '|', grouping1, ')')" } }, "dataSets" : { "action" : { "narrative" : { "title" : "Maximum grip aperture (on reach to grasp)", "intro" : "The maximum grip aperture is the maximum distance between the markers on the thumb and index finger during the period between when the hand left the table and when it touched the stick (this period is labeled as *grip* in our annotation system)." }, "processing" : { "filterString" : "type == 'ACTION' & period == 'GRIP'", "processFunction" : "maxGripFinder", "processFunctionOptions": { "percOcclusion" : 0.05 } }, "defaultAnalysis" : "maxGrip.stickAsContinuous" } }, "dataPreProcessing" : ["data$stick <- factor(as.character(data$stick), levels = c('five', 'seven', 'nine', 'eleven'))", "data$stickcmCentered <- data$stickcm - 8"], "dataSetPostProcessing" : [ "contrasts(dataSetData[['data']]$stick) <- contr.treatment(levels(dataSetData[['data']]$stick), base = 2) # make seven the reference level", "dataSetData[['data']]$stickFiveRef <- dataSetData[['data']]$stick", "contrasts(dataSetData[['data']]$stickFiveRef) <- contr.treatment(levels(dataSetData[['data']]$stickFiveRef), base = 1)", "dataSetData[['data']]$stickNineRef <- dataSetData[['data']]$stick", "contrasts(dataSetData[['data']]$stickNineRef) <- contr.treatment(levels(dataSetData[['data']]$stickNineRef), base = 3)", "dataSetData[['data']]$stickElevenRef <- dataSetData[['data']]$stick", "contrasts(dataSetData[['data']]$stickElevenRef) <- contr.treatment(levels(dataSetData[['data']]$stickElevenRef), base = 4)" ] }
There are four main areas of information variableExplanations
, models
, dataSets
, and dataPreProcessing
Each will be described in detail below:
variableExplanations
This contains explanatory descriptions of each of the variables that are used in a model/analysis. These are required to be named with the same name as the column that they refer to in the data. These only have to be specified once even if they are used in many many models. This section looks like (this is copied from above):
"variableExplanations" : { "stickcmScaled" : "the size of the stick in centimeters (centered at 8 cm, where 1 unit difference is 1 cm difference in stick size)", "fins" : "the configuration of the fins (closed, none, open; where closed is the reference level)", "stickcmScaledXfins" : "the interaction between the size of the stick and configuration of fins", "maxGrip" : "maximum grip aperture (in mm)", "obsisSubj" : "by subject" },
models
This section contains information to fit different kinds of (linear regression) models. Each model can be applied to different dataSets, although the dataSet must have all of the variables (outcome
, predictor1
, predictor2
, and grouping1
) in order for it to fit. Then there are two different sections (analyses
and modelStructures
) described in turn.
analyses
This section contains information about what variables will be used in the models. Each model has a name (this model is named maxGrip.stickAsContinuous
) that is a short description of what is going on. When you fit the models, this will be how you find these models in the data
object. Each model also must have four variables contained in variablesToUse
.
outcome
This is the outcome (dependent) variable in the linear model, in this example it is maxGrip
predictor1
This is the first predictor (independent) variable in the linear model, in this example it is stickcmScaled
predictor2
This is the second predictor (independent) variable in the linear model, in this example it is fins
grouping1
This is the grouping parameter (also known as levels for mixed effects) for most models (including the one here) this should be obsisSubj
"models" : { "analyses" : { "maxGrip.stickAsContinuous" : { "variablesToUse" : { "outcome" : "maxGrip", "predictor1" : "stickcmScaled", "predictor2" : "fins", "grouping1" : "obsisSubj" } } },
There are a number of analyses that are built in to mocapGrip. The following are all of the current possibilties:
maxGrip.stickAsContinuous
An analyses where the outcome is the maximum grip, and the predictors are stick size (as a continuous variable, in cm, where 0=7cm) and the configuration of the fins (categorical, reference level: closed) and the grouping variable is subject. meanGrip.stickAsContinuous
An analyses where the outcome is the mean grip, and the predictors are stick size (as a continuous variable, in cm, where 0=7cm) and the configuration of the fins (categorical, reference level: closed) and the grouping variable is subject. medianGrip.stickAsContinuous
An analyses where the outcome is the median grip, and the predictors are stick size (as a continuous variable, in cm, where 0=7cm) and the configuration of the fins (categorical, reference level: closed) and the grouping variable is subject. maxGrip.stickAsCategorical
An analyses where the outcome is the maximum grip, and the predictors are stick size (as a categorical variable, reference level: seven cm) and the configuration of the fins (categorical, reference level: closed) and the grouping variable is subject. meanGrip.stickAsCategorical
An analyses where the outcome is the mean grip, and the predictors are stick size (as a categorical variable, reference level: seven cm) and the configuration of the fins (categorical, reference level: closed) and the grouping variable is subject. medianGrip.stickAsCategorical
An analyses where the outcome is the median grip, and the predictors are stick size (as a categorical variable, reference level: seven cm) and the configuration of the fins (categorical, reference level: closed) and the grouping variable is subject. modelStructures
This section describes how the variables should be used within the models. Specifically, this part specifies if the variables should be included as just the predictor, or if they should also be included in interactions. When you run the analysis from the section above, each of these formulas will be used, and then one will be selected as the best (based on the options for findtheBest()
or fitAllModels()
). This section will always be named modelStructures
. Each structure within will have a name and then a string that tells R
how to make the formula for lme4
. The format for the formula lists each of the variables, with the formula syntax (e.g. ~
, +
, *
), in quotes, all surrounded by paste0()
so that when they are needed the variable names that are specified above can be put together with the formula syntax and be made into a full formula. For more details about these formulas, see section 2 of Fitting Linear Mixed-Effects Models using lme4.
For the most part, these should be sufficient for most models. Adding different configurations should be done with care.
interactionInPredAndGroup
This includes all possible interactions in both the predictors (sometimes called main effects) and the slope adjustments (aka mixed effects) interactionInPred
This includes all possible interactions in the predictors (sometimes called main effects) but not in the the slope adjustments (aka mixed effects)
formula: maxGrip~stickcmScaled*fins+(1+stickcmScaled+fins|obsisSubj)
noInteractions
This has no interactions in either the predictors (sometimes called main effects) or the slope adjustments (aka mixed effects)
formula: maxGrip~stickcmScaled+fins+(1+stickcmScaled+fins|obsisSubj)
"modelStructures" : { "interactionInPredAndGroup" : "paste0(outcome, '~', predictor1, '*', predictor2, '+', '(', '1+', predictor1, '*', predictor2, '|', grouping1, ')')", "interactionInPred" : "paste0(outcome, '~', predictor1, '*', predictor2, '+', '(', '1+', predictor1, '+', predictor2, '|', grouping1, ')')", "noInteraction" : "paste0(outcome, '~', predictor1, '+', predictor2, '+', '(', '1+', predictor1, '+', predictor2, '|', grouping1, ')')" } },
dataSets
This section specifies the dataSet to be read and processed from the extracted annotations data. This defines what aspects of the data should be extracted, gives some narratives to be used in reports, and has one or more default analyses to run.
"dataSets" : { "action" : { "narrative" : { "title" : "Maximum grip aperture (on reach to grasp)", "intro" : "The maximum grip aperture is the maximum distance between the markers on the thumb and index finger during the period between when the hand left the table and when it touched the stick (this period is labeled as *grip* in our annotation system)." }, "processing" : { "filterString" : "type == 'ACTION' & period == 'GRIP'", "processFunction" : "maxGripFinder", "processFunctionOptions": { "percOcclusion" : 0.05 } }, "defaultAnalysis" : "maxGrip.stickAsContinuous" } }
narrative
sectionThese details are used in the report to describe the data that is used.
title
short title for the section of the report discussing this dataSet.intro
a more detailed description of the dataSet"narrative" : { "title" : "Maximum grip aperture (on reach to grasp)", "intro" : "The maximum grip aperture is the maximum distance between the markers on the thumb and index finger during the period between when the hand left the table and when it touched the stick (this period is labeled as *grip* in our annotation system)." },
processing
sectionThis section defines how to extract the dataSet from the full data.
processing
specifies the type
and period
(or other columns in the data) to select for the dataSet. In this example only the grip periods of action trials will be extracted.
processFunction
this is the function that processes the data. It can be any of the following possibilities:
maxGripFinder
extracts the maximum grip and the percentage of the way through the grip that that maximum happens for the whole dataSet.percOcclusion
the maximum allowable occlusion as a percentage (in decimal notation). Default: 0.05 (meaning 5%) meanMedianGripFinder
extracts the mean and median of grip for the whole dataSet.
options: percOcclusion
the maximum allowable occlusion as a percentage (in decimal notation). Default: 0.05 (meaning 5%) meanMedianSubsetFinder
this extracts the mean and the median from a subset of the duration of the period. The start and stop times are given as options, as well as if those should be interpreted as percentage of period or as miliseconds.
options: percOcclusion
the maximum allowable occlusion as a percentage (in decimal notation). Default: 0.05 (meaning 5%) start
time to start the subset. If percentage this should be greater than or equal to 0 (which means 0%) and less than 1 (which means 100%). If milliseconds, it should be greater than 0, but less than the duration of the period (warnings will be producded if this period does not contain any data)stop
time to stop the subset. If percentage this should be greater than 0 (which means 0%) and less than or equal to 1 (which means 100%). If milliseconds, it should be greater than 0, but less than the duration of the period (warnings will be producded if this period does not contain any data)timeType
should the times above be interpreted as percentages (percent
) of the time period or miliseconds (msecs
)ceilingFinder
find the mean and the median of a grip that is in a band at the top of the range. How large of a band is used is defined by the bandWidth
option below. The data also includes a measure of how long during the period the grip is within this band (column name: durInBand
, in msecs).
options: percOcclusion
the maximum allowable occlusion as a percentage (in decimal notation). Default: 0.05 (meaning 5%)bandWidth
the width of the band at the top of the grip range. In either millimeters or as a percentage of the total grip range (for this period)bandType
should the value in bandWidth
be interpreted as millimeters (mm
) or a percentage (percent
)processFunctionOptions
Options to be passed to the processing function. This should always include percentOcclusion, but may include others, as described above for each processFunction
"processing" : { "processing" : "type == 'ACTION' & period == 'GRIP'", "processFunction" : "maxGripFinder", "processFunctionOptions": { "percOcclusion" : 0.05 } },
defaultAnalysis
sectiondefaultAnalysis
this is the default analysis to be used. This must be the name of one of the analyses in the analyses
section above. This can also be a list (e.g. ["maxGrip.stickAsContinuous", "maxGrip.stickAsCategorical"]
)
"defaultAnalysis" : "maxGrip.stickAsContinuous"
dataPreProcessing
sectionThis section has a list of commands to run before processing any of the dataSets. This is where you can make transformations on all of the data. The data is a large dataframe called data
.
"dataPreProcessing" : ["data$stick <- factor(as.character(data$stick), levels = c('five', 'seven', 'nine', 'eleven'))", "data$stickcmCentered <- data$stickcm - 8"]
dataSetPostProcessing
sectionThis section has a list of commands to run after the processing of each of the dataSets. This is where you can change reference levels or create new variables that don't survive processing. The data frame here is called dataSetData[['data']]
. The example here makes sure that the stick size that is the reference level of the categorical (factor) variable is seven (the second in the ordered list, hence using base=2
). Additionally, new variables (stickFiveRef
, stickNineRef
, and stickElevenRef
) are created for each level as the reference if needed in the future.
"dataSetPostProcessing" : [ "contrasts(dataSetData[['data']]$stick) <- contr.treatment(levels(dataSetData[['data']]$stick), base = 2) # make seven the reference level", "dataSetData[['data']]$stickFiveRef <- dataSetData[['data']]$stick", "contrasts(dataSetData[['data']]$stickFiveRef) <- contr.treatment(levels(dataSetData[['data']]$stickFiveRef), base = 1)", "dataSetData[['data']]$stickNineRef <- dataSetData[['data']]$stick", "contrasts(dataSetData[['data']]$stickNineRef) <- contr.treatment(levels(dataSetData[['data']]$stickNineRef), base = 3)", "dataSetData[['data']]$stickElevenRef <- dataSetData[['data']]$stick", "contrasts(dataSetData[['data']]$stickElevenRef) <- contr.treatment(levels(dataSetData[['data']]$stickElevenRef), base = 4)" ]
If the modelMetadata that is included with the package does not cover your needs, you can write a new one that includes different analyses. The first step in writing your own should be to write a copy of the modelMetadata
included with the package to see what a complete modelMetadata file looks like:
writeModelMetadata(modelMd = modelMetada, path = "./defaultModelMetadata.json")
This file is saved as a json file (in this example it will be named defaultModelMetadata.json
, in R's working directory). You should use this file as a template to add new sections in the format described above. When you are done, you need to read your new modelMetdata json file into a new modelMetadata
object. This function will not only read in and parse the json file, but it will also run some checks on the information that is inside the json file to make sure that it conforms to the structure for model metadata objects which will create a new object called newModelMetadata
. If you see an error or warning, read the following section which helps with some common errors.
newModelMetadata <- readModelMetadata(file = "./editedModelMetadata.json")
If you see an error that looks similar to:
Error in feed_push_parser(readBin(con, raw(), n), reset = TRUE) : parse error: invalid object key (must be a string) "obsisSubj" : "by subject", }, "models" : { "analysisSke (right here) ------^
This means that the json file you've provided does not have the right format for json files. Likely there is a missing or extra comma or misplaced bracket. The json parser tries to tell you where the error is, but it is not always accurate.
The errors that are displayed if the modelMetadata structure being run in does not conform to what the package expects will have some details about possible fixes.
Now that you have the new model metadata object newModelMetadata
, you can pass that as the modelMd
argument to any mocapGrip functions that have that argument. When you pass your new model metadata to a function, that function will use that metadata to extract, analyze, etc. the data.
The following functions can take this new model metadata object as an argument:
addAnalysesToRun.Rd
addNewDataSets.Rd
fitModels.Rd
makeReport.Rd
modelAllData.Rd
readExtractedMocapData.Rd
* removeAnalysesToRun.Rd
If you extract a new dataSet with a new model metadata object, you will need to use that model metadata object with each subsequent command that you run with that data object (e.g. modelAllData()
and makeReport()
).
Adding or changing model metadata objects should be done with care. Some changes are simple (e.g. adding additional information to a narrative section for a variable that already exists), but others are more complicated and could require adding new code to the package (e.g. making a new dataSet specification that needs a new processing function.). You can use trial and error to see if the changes you are making work. You can always access the model metadata object that comes with the pacakge with the object name mocapGrip::modelMetadata
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.