#' write csvs of data from a data object
#' @param data a data object to use for writing data.
#' @param namePrefix a character string to prepend to each file. Default: ""
#' @param path a character string of the path to save the data. Default: "./"
#' @param overwrite logical, should the writer overwrite files that already exist? Default: `FALSE`
#' @return None
#'
#' @export
writeCSVsFromData <- function(data, namePrefix = "", path="./", overwrite = FALSE) {
dataNames <- names(data)
dataNames <- dataNames[dataNames != "fullData"]
filenamesout <- paste0(path, namePrefix, dataNames, ".csv")
# test if file exists
if(!overwrite & any(file.exists(filenamesout))) {
stop("At least one of the files (", filenamesout, ") already exist. Use overwrite = TRUE to overwrite them.")
}
dataSansFullData <- data[names(data) != "fullData"]
result <- mapply(function(dataSet, filenameout) {readr::write_csv(dataSet$data, filenameout)}, dataSansFullData, filenamesout)
sapply(names(result), function(dataSet){
message("Successfully wrote the ", dataSet, " data to ", result[[dataSet]])
}, simplify = TRUE, USE.NAMES = FALSE)
return(invisible())
}
#' display the models that are set to run for one dataSet
#'
#' \bold{Warning:} the name must match the dataSet
#'
#' @param name the name of the dataSet
#' @param dataSet a dataSet
#' @return named character vectors of models to run.
#'
displayAnalysesToRunOne <- function(name, dataSet) {
modelsToRun <- dataSet$analysesToRun
msg <- paste0(paste0(name, ":\n"), paste0("\t", modelsToRun, "\n", collapse=""))
message(msg)
names(modelsToRun) <- name
return(modelsToRun)
}
#' display the models that are set to run for all data
#'
#' @param data a \code{data} object
#' @return named character vectors of models to run.
#'
#' @export
displayAnalysesToRun <- function(data) {
message("Analyses set to run by dataSet\n------------------------------")
# names without fulldata
dataSetNames <- names(data)[names(data) != "fullData"]
out <- sapply(dataSetNames, function(dataSet) {displayAnalysesToRunOne(dataSet, data[[dataSet]])}, simplify = TRUE, USE.NAMES = TRUE)
return(out)
}
# determine which models are compatible with a dataSet based on what columns the dataSet has.
possibleModels <- function(dataSet, modelMd = modelMetadata) {
varsAvail <- names(dataSet$data)
analysesAvail <- modelMd$models$analyses
varsCompatible <- sapply(names(analysesAvail), function(analysis){
all(analysesAvail[[analysis]]$variablesToUse %in% varsAvail)
},simplify = TRUE, USE.NAMES = TRUE)
names(varsCompatible[varsCompatible])
}
promptForModelInput <- function(msg){
resp <- readline(paste0(msg, " (separated by commas): "))
# process the response
selectedModels <- sapply(strsplit(resp, ","), sub, pattern="\\s+", replacement="", simplify = TRUE, USE.NAMES = FALSE)
return(selectedModels)
}
# \bold{Warning:} the name must match the dataSet
addAnalysesToRunOne <- function(name, dataSet, modelMd = modelMetadata){
message("Analyses set to run already for the dataSet ", appendLF = FALSE)
# grab the old models, figure out posssible models,
# and subset possible models that are not attached
oldModels <- displayAnalysesToRunOne(name, dataSet)
possModels <- possibleModels(dataSet)
newModels <-possModels[!possModels %in% oldModels]
# add numbers to the new models
names(newModels) <- c(1:length(newModels))
# prompt the user
message("Possible additional models are:\n", appendLF = FALSE)
message(paste0("\t", paste0(names(newModels), ") ", newModels), "\n", collapse=""))
selectedModels <- promptForModelInput("Select models to add")
# check the response, reprompt if there are not at least one number in each response.
while(any(!selectedModels %in% names(newModels))) {
message("Please select the model by number.")
selectedModels <- promptForModelInput("Select models to add")
}
modelsOut <- c(oldModels, newModels[names(newModels) %in% selectedModels])
names(modelsOut) <- NULL
return(modelsOut)
}
#' add models to the analysesToRun list.
#'
#' @param data a \code{data} object
#' @param modelMd a \code{modelMetadata} object to retrieve analyses from, by default the package's \code{modelMetadata}
#' @return a \code{data} object
#'
#' @export
addAnalysesToRun <- function(data, modelMd = modelMetadata) {
# names without fulldata
dataSetNames <- names(data)[names(data) != "fullData"]
# prompt for models
newModels <- sapply(dataSetNames, function(dataSet) {addAnalysesToRunOne(dataSet, data[[dataSet]], modelMd)}, simplify = FALSE, USE.NAMES = TRUE)
# add new models to data
for(dataSet in names(newModels)) {
data[[dataSet]]$analysesToRun <- newModels[[dataSet]]
}
return(data)
}
# \bold{Warning:} the name must match the dataSet
removeAnalysesToRunOne <- function(name, dataSet, modelMd = modelMetadata){
message("Analyses set to run already for the dataSet ", appendLF = FALSE)
# grab the old models, figure out posssible models,
# and subset possible models that are not attached
oldModels <- displayAnalysesToRunOne(name, dataSet)
# add numbers to the old models
names(oldModels) <- c(1:length(oldModels))
# prompt the user
message("Models to remove:\n", appendLF = FALSE)
message(paste0("\t", paste0(names(oldModels), ") ", oldModels), "\n", collapse=""))
selectedModels <- promptForModelInput("Select models to remove")
if(!selectedModels %in% c("none", "None", "NONE")){
# if the resposne is not an escape string
# check the response, reprompt if there are not at least one number in each response.
while(any(!{selectedModels %in% names(oldModels)})) {
message("Please select the model by number. Type 'none' to keep all models present.")
selectedModels <- promptForModelInput("Select models to remove")
if(selectedModels %in% c("none", "None", "NONE")) { break }
}
}
modelsOut <- oldModels[!names(oldModels) %in% selectedModels]
names(modelsOut) <- NULL
return(modelsOut)
}
#' add models to the analysesToRun list.
#'
#' @param data a \code{data} object
#' @param modelMd a \code{modelMetadata} object to retrieve analyses from, by default the package's \code{modelMetadata}
#' @return a \code{data} object
#'
#' @export
removeAnalysesToRun <- function(data, modelMd = modelMetadata) {
# names without fulldata
dataSetNames <- names(data)[names(data) != "fullData"]
# prompt for models
newModels <- sapply(dataSetNames, function(dataSet) {removeAnalysesToRunOne(dataSet, data[[dataSet]], modelMd)}, simplify = FALSE, USE.NAMES = TRUE)
# add new models to data
for(dataSet in names(newModels)) {
# warn if there are no models left
if(length(newModels[[dataSet]]) == 0) {warning("There are no more analysesToRun for dataSet ", dataSet, ". This means no models will be fit for it if you don't add other models.")}
data[[dataSet]]$analysesToRun <- newModels[[dataSet]]
}
return(data)
}
#' check the form of data object
#'
#' @param data a data object to be checked
#' @param modelMd a modelStructure to use (to confirm that the dataSets are in the modelStructure)
#'
#' @return if the data objects form is correct, the data object
#'
#' @export
checkData <- function(data, modelMd) {
errormsg <- "The data object supplied does not have the right form. If you've changed the data object since it was created by the readExtractedMocapData() function, something went wrong with those changes. Please try runing readExtractedMocapData() again, and using that object, if that works, try your changes one by one to see which of the changes is causing the problem."
if( !is.list(data) ) { stop(errormsg) }
if( length(data) < 1 ) { stop(errormsg) }
# check that the names of data are names of dataSets in modelMd (or fullData)
dataSetNames <- names(data)
if(!all(dataSetNames %in% c(names(modelMd$dataSets), "fullData"))) { stop(errormsg, dataSet, "names of the dataSets") }
dataSetNames <- dataSetNames[dataSetNames!="fullData"]
for(dataSet in dataSetNames) {
# check that the names within each dataSet are correct
dataSetSubNames <- names(data[[dataSet]])
if(!all(dataSetSubNames %in% c("data", "warnings", "analysesToRun", "analyses"))) {stop(errormsg, dataSet, ": names within the dataSet") }
for(dataSetSub in dataSetSubNames) {
# check that the dataSetSub structures are the right type
if(dataSetSub == "data") {
if(!is.data.frame(data[[dataSet]][[dataSetSub]])) { stop(errormsg, dataSet, ": data") }
}
if(dataSetSub == "warnings") {
if(!is.list(data[[dataSet]][[dataSetSub]])) { stop(errormsg, dataSet, ": warnings") }
}
if(dataSetSub == "analysesToRun") {
# check that these are in the modelMd?
if(!is.character(data[[dataSet]][[dataSetSub]])) { stop(errormsg, dataSet, ": analysesToRun") }
}
if(dataSetSub == "analyses") {
if(!is.list(data[[dataSet]][[dataSetSub]])) { stop(errormsg, dataSet, ": analyses") }
}
}
}
return(data)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.