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.

modelMetadata json file structure

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.

"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:

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.

"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 section

These details are used in the report to describe the data that is used.

"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 section

This 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:

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 section

defaultAnalysis 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 section

This 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 section

This 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)"
]   

replacing the default modelMetadata

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



jonkeane/mocapGrip documentation built on May 19, 2019, 7:30 p.m.