From c080373e1cc0ed1c9148ea1920abff48a09816ae Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 27 Sep 2022 09:29:46 -0400 Subject: [PATCH] Fixes #876 introduce default statistics Fixes #875 superscript th --- NAMESPACE | 8 + R/messages.R | 3 + R/reportingengine-env.R | 130 +++++++- R/task-settings.R | 75 ++++- R/utilities-goodness-of-fit.R | 391 ++++++++++++++++--------- R/utilities-observed-data.R | 28 +- R/utils.R | 60 ++++ man/AllAvailableTasks.Rd | 3 +- man/ApplicationRanges.Rd | 3 +- man/DataSelectionKeys.Rd | 3 +- man/GofTaskSettings.Rd | 115 +++++++- man/PopulationWorkflowTypes.Rd | 3 +- man/ResidualScales.Rd | 3 +- man/StandardPlotTasks.Rd | 3 +- man/StandardSimulationTasks.Rd | 3 +- man/StatisticsTypes.Rd | 39 +++ man/geomean-slash-sd.Rd | 19 ++ man/geomean-times-sd.Rd | 19 ++ man/geomean.Rd | 19 ++ man/getObservedDataFromOutput.Rd | 4 +- man/getPopulationResultsFromOutput.Rd | 4 +- man/getSimulatedResultsFromOutput.Rd | 4 +- man/getStatisticsFromType.Rd | 23 ++ man/pkDictionaryQualificationOSP.Rd | 2 +- man/plotMeanTimeProfile.Rd | 2 +- man/plotMeanTimeProfileLog.Rd | 34 +++ man/plotPopulationTimeProfileLog.Rd | 34 +++ man/removeNegativeValues.Rd | 20 ++ man/setDefaultTimeProfileStatistics.Rd | 42 +++ 29 files changed, 931 insertions(+), 165 deletions(-) create mode 100644 man/StatisticsTypes.Rd create mode 100644 man/geomean-slash-sd.Rd create mode 100644 man/geomean-times-sd.Rd create mode 100644 man/geomean.Rd create mode 100644 man/getStatisticsFromType.Rd create mode 100644 man/plotMeanTimeProfileLog.Rd create mode 100644 man/plotPopulationTimeProfileLog.Rd create mode 100644 man/removeNegativeValues.Rd create mode 100644 man/setDefaultTimeProfileStatistics.Rd diff --git a/NAMESPACE b/NAMESPACE index 8e688f97..270a5531 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,5 +1,7 @@ # Generated by roxygen2: do not edit by hand +export("geomean*sd") +export("geomean/sd") export(AggregationConfiguration) export(AllAvailableTasks) export(ApplicationRanges) @@ -23,6 +25,7 @@ export(SensitivityPlotSettings) export(SimulationSet) export(StandardPlotTasks) export(StandardSimulationTasks) +export(StatisticsTypes) export(Task) export(activateWorkflowTasks) export(addFigureChunk) @@ -57,6 +60,7 @@ export(defaultSimulationNumberOfCores) export(defaultVariationRange) export(evalDataFilter) export(generateResultFileNames) +export(geomean) export(getAnchorName) export(getDefaultDemographyXParameters) export(getDefaultPKParametersXParameters) @@ -74,6 +78,7 @@ export(getResiduals) export(getSimulationDescriptor) export(getSimulationParameterDisplayPaths) export(getSimulationResultFileNames) +export(getStatisticsFromType) export(getTaskInputs) export(getWorkflowParameterDisplayPaths) export(getXParametersForDemogrpahyPlot) @@ -117,7 +122,9 @@ export(plotMassBalanceCumulativeTimeProfile) export(plotMassBalancePieChart) export(plotMassBalanceTimeProfile) export(plotMeanTimeProfile) +export(plotMeanTimeProfileLog) export(plotPopulationTimeProfile) +export(plotPopulationTimeProfileLog) export(prettyCaption) export(ratioBoxplot) export(readObservedDataFile) @@ -135,6 +142,7 @@ export(setDefaultPlotFormat) export(setDefaultStairstep) export(setDefaultTheme) export(setDefaultThemeFromJson) +export(setDefaultTimeProfileStatistics) export(setPlotFormat) export(setSimulationDescriptor) export(setWatermarkConfiguration) diff --git a/R/messages.R b/R/messages.R index c4a48045..4fce949f 100644 --- a/R/messages.R +++ b/R/messages.R @@ -277,6 +277,9 @@ messages <- list( }, completedOnCores = function(objectNames) { paste0(objectNames, " successfully completed on all cores") + }, + negativeDataRemoved = function(n) { + paste0(n, " negative or null values were removed from logarithmic plot") } ) diff --git a/R/reportingengine-env.R b/R/reportingengine-env.R index 6f248785..381f4988 100644 --- a/R/reportingengine-env.R +++ b/R/reportingengine-env.R @@ -97,7 +97,6 @@ reEnv$ddiRatioSubsetsDictionary <- list( # Default value for a scale factor used in a parallel simulation. The product of this scale factor and the number of allowable cores (allowedCores) sets the maximum number of simulations that may be run on one core. reEnv$defaultMaxSimulationsPerCore <- 2 - #' @title setWatermarkConfiguration #' @description Set default watermark configuration for current theme #' @param watermark character or \code{Label} class object from `tlf` package @@ -250,3 +249,132 @@ setDefaultAutoAxisLimitMargin <- function(margin) { validateIsNumeric(margin) reEnv$autoAxisLimitMargin <- margin } + +#' @title StatisticsTypes +#' @description List of available statistic types summarizing data for time profile plots +#' \itemize{ +#' \item `"2.5th-97.5th Percentiles"` summarizes data using median, 2.5th and 97.5th percentiles +#' \item `"5th-95th Percentiles"` summarizes data using median, 5th and 95th percentiles +#' \item `"10th-90th Percentiles"` summarizes data using median, 10th and 90th percentiles +#' \item `"Geometric mean"` summarizes data using geometric mean and mean */ geometric standard deviation +#' \item `"Arithmetic mean"` summarizes data using arithmetic mean and mean +/- standard deviation +#' } +#' +#' @export +#' @family enum helpers +#' @examples dontrun{ +#' getStatisticsFromType(StatisticsTypes) +#' } +StatisticsTypes <- enum(c( + "2.5th-97.5th Percentiles", + "5th-95th Percentiles", + "10th-90th Percentiles", + "Geometric mean", + "Arithmetic mean" +)) + + +#' @title getStatisticsFromType +#' @description Get statistics +#' @param statisticsType Statistics summarizing time profile simulated data +#' as defined by helper enum `StatisticsType` +#' @return A list including `y`, `ymin` and `ymax` summary statistics as well as their `caption` +#' @export +#' @examples dontrun{ +#' workflow$plotTime +#' } +getStatisticsFromType <- function(statisticsType){ + validateIsIncluded(statisticsType, StatisticsTypes) + if(isIncluded(statisticsType, StatisticsTypes$`2.5th-97.5th Percentiles`)){ + return(list( + y = tlf::tlfStatFunctions$`Percentile50%`, + ymin = tlf::tlfStatFunctions$`Percentile2.5%`, + ymax = tlf::tlfStatFunctions$`Percentile97.5%`, + yCaption = "median", + # The unicode characters below are superscript th + rangeCaption = "[2.5\u1d57\u02b0-97.5\u1d57\u02b0] percentiles" + )) + } + if(isIncluded(statisticsType, StatisticsTypes$`5th-95th Percentiles`)){ + return(list( + y = tlf::tlfStatFunctions$`Percentile50%`, + ymin = tlf::tlfStatFunctions$`Percentile5%`, + ymax = tlf::tlfStatFunctions$`Percentile95%`, + yCaption = "median", + rangeCaption = "[5\u1d57\u02b0-95\u1d57\u02b0] percentiles" + )) + } + if(isIncluded(statisticsType, StatisticsTypes$`10th-90th Percentiles`)){ + return(list( + y = tlf::tlfStatFunctions$`Percentile50%`, + ymin = tlf::tlfStatFunctions$`Percentile10%`, + ymax = tlf::tlfStatFunctions$`Percentile90%`, + yCaption = "median", + rangeCaption = "[10\u1d57\u02b0-90\u1d57\u02b0] percentiles" + )) + } + if(isIncluded(statisticsType, StatisticsTypes$`Arithmetic mean`)){ + return(list( + y = tlf::tlfStatFunctions$mean, + ymin = tlf::tlfStatFunctions$`mean-sd`, + ymax = tlf::tlfStatFunctions$`mean+sd`, + yCaption = "arithmetic mean", + # The unicode character below is +/- symbol + rangeCaption = "mean \u00b1 SD range" + )) + } + #TODO : define geometric mean in tlf ! + return(list( + y = "geomean", + ymin = "geomean/sd", + ymax = "geomean*sd", + yCaption = "geometric mean", + # The unicode character below is supposed to be */ symbol + rangeCaption = "mean \u22c7 geometric SD range" + )) +} + +reEnv$defaultTimeProfileStatistics <- getStatisticsFromType(StatisticsTypes$`5th-95th Percentiles`) + +#' @title setDefaultTimeProfileStatistics +#' @description Set default statistics used in population time profiles and residuals plots +#' @param statisticsType Name of statistics type as defined in enum `StatisticsTypes` +#' @param y Function or function name for middle values statistics +#' @param ymin Function or function name for min values statistics +#' @param ymax Function or function name for max values statistics +#' @param yCaption Legend caption for middle values statistics +#' @param rangeCaption Legend caption for range values statistics +#' @export +#' @examples \dontrun{ +#' # Set the default statistics as geometric mean +#' setDefaultTimeProfileStatistics(statisticsType = StatisticsTypes$`Geometric mean`) +#' +#' # Set the default legend caption displayed for range +#' setDefaultTimeProfileStatistics(rangeCaption = "90% population range") +#' +#' } +#' +setDefaultTimeProfileStatistics <- function(statisticsType = NULL, + y = NULL, + ymin = NULL, + ymax = NULL, + yCaption = NULL, + rangeCaption = NULL){ + + validateIsIncluded(statisticsType, StatisticsTypes, nullAllowed = TRUE) + # Allow user to enter the function directly + validateIsOfType(y, c("character", "closure"), nullAllowed = TRUE) + validateIsOfType(ymin, c("character", "closure"), nullAllowed = TRUE) + validateIsOfType(ymax, c("character", "closure"), nullAllowed = TRUE) + + if(!isEmpty(statisticsType)){ + reEnv$defaultTimeProfileStatistics <- getStatisticsFromType(statisticsType) + } + # Assign variables to reEnv only if defined + eval(parseVariableToObject( + objectName = "reEnv$defaultTimeProfileStatistics", + variableName = c("y", "ymin", "ymax", "yCaption", "rangeCaption"), + keepIfNull = TRUE)) + + return(invisible()) +} diff --git a/R/task-settings.R b/R/task-settings.R index 14d96ea7..4d0a7da0 100644 --- a/R/task-settings.R +++ b/R/task-settings.R @@ -4,6 +4,8 @@ #' @keywords internal TaskSettings <- R6::R6Class( "TaskSettings", + # This allows the R6 class to accept new fields + lock_objects = FALSE, public = list( #' @description #' Create a `TaskSettings` object @@ -147,18 +149,83 @@ GofTaskSettings <- R6::R6Class( public = list( #' @field referenceData Data results obtained by TimeProfilesAndResiduals task corresponding to referencePopulation referenceData = NULL, - + #' @description #' Create a `GofTaskSettings` object #' @param taskName name of the task using the settings #' @param outputSelections subset of simulationSet outputs to be used in GoF plot + #' @param statisticsType Statistics summarizing time profile simulated data #' @return A new `GofTaskSettings` object - initialize = function(taskName = AllAvailableTasks$plotTimeProfilesAndResiduals, outputSelections = NULL) { + initialize = function(taskName = AllAvailableTasks$plotTimeProfilesAndResiduals, + outputSelections = NULL, + statisticsType = NULL) { validateIsIncluded(taskName, AllAvailableTasks$plotTimeProfilesAndResiduals) + validateIsIncluded(statisticsType, StatisticsTypes, nullAllowed = TRUE) + super$initialize(taskName) + private$.includeReferenceData <- TRUE private$.outputSelections <- outputSelections + private$.statistics <- reEnv$defaultTimeProfileStatistics + self$setStatistics(statisticsType = statisticsType) + + }, + + #' @description Set statistics used in population time profiles and residuals plots + #' @param statisticsType Name of statistics type as defined in enum `StatisticsTypes` + #' @param y Function or function name for middle values statistics + #' @param ymin Function or function name for min values statistics + #' @param ymax Function or function name for max values statistics + #' @param yCaption Legend caption for middle values statistics + #' @param rangeCaption Legend caption for range values statistics + #' @examples \dontrun{ + #' # Set the statistics as geometric mean + #' workflow$plotTimeProfilesAndResiduals$settings$setStatistics( + #' statisticsType = StatisticsTypes$`Geometric mean` + #' ) + #' + #' # Set the legend caption displayed for range + #' workflow$plotTimeProfilesAndResiduals$settings$setStatistics( + #' statisticsType = StatisticsTypes$`Geometric mean` + #' rangeCaption = "90% population range" + #' ) + #' + #' } + #' + setStatistics = function(statisticsType = NULL, + y = NULL, + ymin = NULL, + ymax = NULL, + yCaption = NULL, + rangeCaption = NULL){ + + validateIsIncluded(statisticsType, StatisticsTypes, nullAllowed = TRUE) + # Allow user to enter the function directly + validateIsOfType(y, c("character", "closure"), nullAllowed = TRUE) + validateIsOfType(ymin, c("character", "closure"), nullAllowed = TRUE) + validateIsOfType(ymax, c("character", "closure"), nullAllowed = TRUE) + + if(!isEmpty(statisticsType)){ + private$.statistics <- getStatisticsFromType(statisticsType) + } + # Assign variables to reEnv only if defined + eval(parseVariableToObject( + objectName = "private$.statistics", + variableName = c("y", "ymin", "ymax", "yCaption", "rangeCaption"), + keepIfNull = TRUE)) + return(invisible()) + }, + + #' @description Get statistics used in population time profiles and residuals plots + #' @examples \dontrun{ + #' # Get the statistics of time profiles task + #' workflow$plotTimeProfilesAndResiduals$settings$getStatistics() + #' } + #' + getStatistics = function(){ + return(private$.statistics) } + ), active = list( #' @field includeReferenceData logical defining if reference population should be included in @@ -181,9 +248,11 @@ GofTaskSettings <- R6::R6Class( private$.outputSelections <- value %||% private$.outputSelections return(invisible()) } + ), private = list( .includeReferenceData = NULL, - .outputSelections = NULL + .outputSelections = NULL, + .statistics = NULL ) ) diff --git a/R/utilities-goodness-of-fit.R b/R/utilities-goodness-of-fit.R index d16eb87a..b4b5e273 100644 --- a/R/utilities-goodness-of-fit.R +++ b/R/utilities-goodness-of-fit.R @@ -47,11 +47,11 @@ plotMeanGoodnessOfFit <- function(structureSet, settings = NULL) { simulationPathResults <- ospsuite::getOutputValues(simulationResult, quantitiesOrPaths = output$path) molWeight <- simulation$molWeightFor(output$path) - outputSimulatedResults <- getSimulatedResultsFromOutput(simulationPathResults, output, simulationQuantity, molWeight, structureSet$simulationSet) + outputSimulatedResults <- getSimulatedResultsFromOutput(simulationPathResults, output, simulationQuantity, molWeight, structureSet) outputSimulatedData <- outputSimulatedResults$data outputSimulatedMetaData[[output$path]] <- outputSimulatedResults$metaData - outputObservedResults <- getObservedDataFromOutput(output, observedResult$data, observedResult$dataMapping, molWeight, structureSet$simulationSet$timeUnit) + outputObservedResults <- getObservedDataFromOutput(output, observedResult$data, observedResult$dataMapping, molWeight, structureSet) outputResidualsData <- getResiduals(outputObservedResults$data, outputSimulatedData, output$residualScale) # Build data.frames to be plotted @@ -62,7 +62,7 @@ plotMeanGoodnessOfFit <- function(structureSet, settings = NULL) { } timeProfileData <- rbind.data.frame(observedData, lloqData, simulatedData) - timeProfileMapping <- tlf::XYGDataMapping$new(x = "Time", y = "Concentration", color = "Legend") + timeProfileMapping <- list(x = "Time", y = "Concentration", group = "Legend") resultID <- defaultFileNames$resultID(length(goodnessOfFitResults) + 1, "time_profile_data") @@ -153,14 +153,7 @@ plotMeanGoodnessOfFit <- function(structureSet, settings = NULL) { allResiduals <- goodnessOfFitResiduals[[ApplicationRanges$total]] return(list( results = goodnessOfFitResults, - residuals = ifNotNull( - allResiduals, - list( - data = allResiduals, - metaData = residualsMetaData[[ApplicationRanges$total]] - ), - NULL - ) + residuals = allResiduals )) } @@ -171,24 +164,38 @@ plotMeanGoodnessOfFit <- function(structureSet, settings = NULL) { #' @param output An `Output` object #' @param simulationQuantity Dimension/quantity for unit conversion of dependent variable #' @param molWeight Molar weight for unit conversion of dependent variable -#' @param simulationSet `SimulationSet` object +#' @param structureSet `SimulationStructure` object #' @return list of data and metaData #' @import ospsuite.utils #' @keywords internal -getSimulatedResultsFromOutput <- function(simulationPathResults, output, simulationQuantity, molWeight, simulationSet) { +getSimulatedResultsFromOutput <- function(simulationPathResults, output, simulationQuantity, molWeight, structureSet) { + simulationSet <- structureSet$simulationSet outputConcentration <- simulationPathResults$data[, output$path] - if (!isOfLength(output$displayUnit, 0)) { - outputConcentration <- ospsuite::toUnit(simulationQuantity, + # Output object is updated: displayUnit cannot be empty anymore + output$displayUnit <- output$displayUnit %||% simulationQuantity$displayUnit + + outputSimulatedData <- data.frame( + "Time" = ospsuite::toUnit( + "Time", + simulationPathResults$data[, "Time"], + simulationSet$timeUnit + ), + "Concentration" = ospsuite::toUnit( + simulationQuantity, simulationPathResults$data[, output$path], output$displayUnit, molWeight = molWeight - ) - } - - outputSimulatedData <- data.frame( - "Time" = ospsuite::toUnit("Time", simulationPathResults$data[, "Time"], simulationSet$timeUnit), - "Concentration" = outputConcentration, - "Legend" = paste0("Simulated ", output$displayName %||% output$path, " (", simulationSet$simulationSetName, ")"), + ), + "Legend" = captions$plotGoF$meanLegend( + simulationSetName = simulationSet$simulationSetName, + descriptor = structureSet$simulationSetDescriptor, + pathName = output$displayName + ), + "Legend" = captions$plotGoF$resLegend( + simulationSetName = simulationSet$simulationSetName, + descriptor = structureSet$simulationSetDescriptor, + pathName = output$displayName + ), "Path" = output$path ) @@ -199,7 +206,7 @@ getSimulatedResultsFromOutput <- function(simulationPathResults, output, simulat ), "Concentration" = list( dimension = simulationQuantity$dimension, - unit = output$displayUnit %||% simulationQuantity$displayUnit + unit = output$displayUnit ), "Path" = output$path ) @@ -250,7 +257,7 @@ getResiduals <- function(observedData, "Observed" = observedData[, "Concentration"], "Simulated" = simulatedData[timeMatchedData, "Concentration"], "Residuals" = residualValues, - "Legend" = simulatedData[timeMatchedData, "Legend"], + "Legend" = simulatedData[timeMatchedData, "ResidualsLegend"], "Path" = observedData[, "Path"] ) return(residualsData) @@ -279,12 +286,6 @@ plotPopulationGoodnessOfFit <- function(structureSet, settings = NULL) { goodnessOfFitResults <- list() goodnessOfFitResiduals <- list() - residualsAggregationType <- settings$residualsAggregationType %||% "mean" - selectedVariablesForResiduals <- c("Time", "mean", "legendMean", "Path") - if (residualsAggregationType == "median") { - selectedVariablesForResiduals <- c("Time", "median", "legendMedian", "Path") - } - # Load observed and simulated data re.tStoreFileMetadata(access = "read", filePath = structureSet$simulationSet$simulationFile) simulation <- loadSimulationWithUpdatedPaths(structureSet$simulationSet, loadFromCache = TRUE) @@ -302,16 +303,13 @@ plotPopulationGoodnessOfFit <- function(structureSet, settings = NULL) { simulationPathResults <- ospsuite::getOutputValues(simulationResult, quantitiesOrPaths = output$path) molWeight <- simulation$molWeightFor(output$path) - outputSimulatedResults <- getPopulationResultsFromOutput(simulationPathResults, output, simulationQuantity, molWeight, structureSet$simulationSet, settings) + outputSimulatedResults <- getPopulationResultsFromOutput(simulationPathResults, output, simulationQuantity, molWeight, structureSet, settings) outputSimulatedData <- outputSimulatedResults$data outputSimulatedMetaData[[output$path]] <- outputSimulatedResults$metaData - outputObservedResults <- getObservedDataFromOutput(output, observedResult$data, observedResult$dataMapping, molWeight, structureSet$simulationSet$timeUnit) + outputObservedResults <- getObservedDataFromOutput(output, observedResult$data, observedResult$dataMapping, molWeight, structureSet) - simulatedDataForResiduals <- outputSimulatedData[, selectedVariablesForResiduals] - # getResiduals is based on mean workflow whose names are c("Time", "Concentration", "Legend", "Path") - names(simulatedDataForResiduals) <- c("Time", "Concentration", "Legend", "Path") - outputResidualsData <- getResiduals(outputObservedResults$data, simulatedDataForResiduals, output$residualScale) + outputResidualsData <- getResiduals(outputObservedResults$data, outputSimulatedData, output$residualScale) # Build data.frames to be plotted simulatedData <- rbind.data.frame(simulatedData, outputSimulatedData) @@ -339,7 +337,7 @@ plotPopulationGoodnessOfFit <- function(structureSet, settings = NULL) { timeOffset = structureSet$simulationSet$timeOffset ) - timeProfileMapping <- tlf::XYGDataMapping$new(x = "Time", y = "Concentration", color = "Legend") + timeProfileMapping <- list(x = "Time", y = "Concentration", ymin = "ymin", ymax = "ymax", group = "Legend") # metaDataFrame summarizes paths, dimensions and units metaDataFrame <- getMetaDataFrame(outputSimulatedMetaData) @@ -419,14 +417,7 @@ plotPopulationGoodnessOfFit <- function(structureSet, settings = NULL) { return(list( results = goodnessOfFitResults, referenceData = referenceData, - residuals = ifNotNull( - allResiduals, - list( - data = allResiduals, - metaData = residualsMetaData[[ApplicationRanges$total]] - ), - NULL - ) + residuals = allResiduals )) } @@ -437,14 +428,21 @@ plotPopulationGoodnessOfFit <- function(structureSet, settings = NULL) { #' @param output An `Output` object #' @param simulationQuantity Dimension/quantity for unit conversion of dependent variable #' @param molWeight Molar weight for unit conversion of dependent variable -#' @param simulationSet `SimulationSet` object +#' @param structureSet `SimulationStructure` object #' @param settings TaskSetting object #' @return list of data and metaData #' @import ospsuite.utils #' @keywords internal -getPopulationResultsFromOutput <- function(simulationPathResults, output, simulationQuantity, molWeight, simulationSet, settings = NULL) { - aggregateNames <- c("mean", "median", "lowPerc", "highPerc") - aggregateFunctions <- c(mean, median, AggregationConfiguration$functions$ymin, AggregationConfiguration$functions$ymax) +getPopulationResultsFromOutput <- function(simulationPathResults, output, simulationQuantity, molWeight, structureSet, settings = NULL) { + simulationSet <- structureSet$simulationSet + timeProfileStatistics <- settings$getStatistics() + aggregateNames <- c("y", "ymin", "ymax") + aggregateFunctions <- sapply( + timeProfileStatistics[aggregateNames], + function(functionName) { + match.fun(functionName) + } + ) # Get the aggregated results: mean, median and range along time bins aggregateSummary <- tlf::AggregationSummary$new( @@ -457,29 +455,32 @@ getPopulationResultsFromOutput <- function(simulationPathResults, output, simula ) # Conversion to user-defined units + # Output object is updated: displayUnit cannot be empty anymore + output$displayUnit <- output$displayUnit %||% simulationQuantity$displayUnit # Expressions are used to prevent copy/paste of the code for mean, median and range conversions aggregateData <- aggregateSummary$dfHelper - aggregateData$Time <- toUnit("Time", aggregateData$Time, simulationSet$timeUnit) + aggregateData$Time <- ospsuite::toUnit("Time", aggregateData$Time, simulationSet$timeUnit) convertExpressions <- parse(text = paste0( - "aggregateData$", aggregateNames, "<- ifNotNull(output$displayUnit,", - "toUnit(simulationQuantity, aggregateData$", aggregateNames, ", output$displayUnit, molWeight = molWeight),", - "aggregateData$", aggregateNames, ")" + "aggregateData$", aggregateNames, "<- ", + "ospsuite::toUnit(simulationQuantity, aggregateData$", aggregateNames, + ", output$displayUnit, molWeight = molWeight)" )) eval(convertExpressions) - # Legend using expressions - # The generated code to eval follows the example below - # aggregateData$legendMean <- paste0("Simulated mean for ", - # output$displayName %||% output$path, " (", simulationSet$simulationSetName, ")") - legendExpressions <- parse(text = paste0( - "aggregateData$", c("legendMean", "legendMedian", "legendRange"), - '<- paste0("Simulated ', c("mean", "median", AggregationConfiguration$names$range), - ' for ", output$displayName %||% output$path, " (", simulationSet$simulationSetName, ")")' - )) - eval(legendExpressions) - outputSimulatedData <- aggregateData + outputSimulatedData$Concentration <- outputSimulatedData$y + outputSimulatedData$Legend <- captions$plotGoF$populationLegend( + simulationSetName = simulationSet$simulationSetName, + descriptor = structureSet$simulationSetDescriptor, + statistics = timeProfileStatistics, + pathName = output$displayName + ) + outputSimulatedData$ResidualsLegend <- captions$plotGoF$resLegend( + simulationSetName = simulationSet$simulationSetName, + descriptor = structureSet$simulationSetDescriptor, + pathName = output$displayName + ) outputSimulatedData$Path <- output$path outputSimulatedMetaData <- list( @@ -505,52 +506,107 @@ getPopulationResultsFromOutput <- function(simulationPathResults, output, simula #' @param observedData data.frame of observed data #' @param lloqData data.frame of lloq data #' @param metaData meta data on `data` -#' @param dataMapping `XYGDataMapping` R6 class object from `tlf` library +#' @param dataMapping A list mapping `x`, `y` and `group` from datasets #' @param plotConfiguration `PlotConfiguration` class object from `tlf` library #' @return ggplot object of time profile for mean model workflow #' @export #' @import tlf -#' @import ggplot2 plotMeanTimeProfile <- function(simulatedData, observedData = NULL, lloqData = NULL, metaData = NULL, dataMapping = NULL, plotConfiguration = NULL) { + simulatedDataMapping <- tlf::TimeProfileDataMapping$new( + x = dataMapping$x, + y = dataMapping$y, + group = dataMapping$group + ) + observedDataMapping <- tlf::ObservedDataMapping$new( + x = dataMapping$x, + y = dataMapping$y, + group = dataMapping$group + ) + plotConfiguration <- plotConfiguration %||% TimeProfilePlotConfiguration$new( data = simulatedData, metaData = metaData, - dataMapping = dataMapping + dataMapping = simulatedDataMapping ) - plotConfiguration <- updatePlotConfigurationTimeTicks(simulatedData, metaData, dataMapping, plotConfiguration) + plotConfiguration <- updatePlotConfigurationTimeTicks(simulatedData, metaData, simulatedDataMapping, plotConfiguration) - timeProfilePlot <- tlf::addLine( + timeProfilePlot <- tlf::plotTimeProfile( data = simulatedData, metaData = metaData, - dataMapping = dataMapping, + dataMapping = simulatedDataMapping, + observedData = rbind.data.frame(observedData, lloqData), + observedDataMapping = observedDataMapping, plotConfiguration = plotConfiguration ) - if (!isEmpty(observedData)) { - timeProfilePlot <- tlf::addScatter( - data = observedData, - metaData = metaData, - dataMapping = dataMapping, - plotConfiguration = plotConfiguration, - plotObject = timeProfilePlot - ) + + return(timeProfilePlot) +} + +#' @title plotMeanTimeProfileLog +#' @description Plot time profile for mean model workflow +#' @param simulatedData data.frame of simulated data +#' @param observedData data.frame of observed data +#' @param lloqData data.frame of lloq data +#' @param metaData meta data on `data` +#' @param dataMapping A list mapping `x`, `y` and `group` from datasets +#' @param plotConfiguration `PlotConfiguration` class object from `tlf` library +#' @return ggplot object of time profile for mean model workflow +#' @export +#' @import tlf +plotMeanTimeProfileLog <- function(simulatedData, + observedData = NULL, + lloqData = NULL, + metaData = NULL, + dataMapping = NULL, + plotConfiguration = NULL) { + # Remove 0 values from simulated and observed data + # TODO: use dplyr to refactor the selection + simulatedData <- removeNegativeValues(simulatedData, dataMapping$y) + observedData <- removeNegativeValues(observedData, dataMapping$y) + lloqData <- removeNegativeValues(lloqData, dataMapping$y) + + logObservedValues <- NULL + logLLOQValues <- NULL + if(!isEmpty(observedData)){ + logObservedValues <- observedData[, dataMapping$y] } - if (!isEmpty(lloqData)) { - timeProfilePlot <- tlf::addLine( - data = lloqData, - metaData = metaData, - dataMapping = dataMapping, - plotConfiguration = plotConfiguration, - plotObject = timeProfilePlot - ) + if(!isEmpty(lloqData)){ + logLLOQValues <- lloqData[, dataMapping$y] } - timeProfilePlot <- tlf::setLegendPosition(plotObject = timeProfilePlot, position = reDefaultLegendPosition) - return(timeProfilePlot) + # Get the nice auto scaling of the log data + yAxisLimits <- autoAxesLimits(c( + simulatedData[, dataMapping$y], + simulatedData[, dataMapping$ymin], + simulatedData[, dataMapping$ymax], + logObservedValues, + logLLOQValues + ), + scale = "log" + ) + yAxisTicks <- autoAxesTicksFromLimits(yAxisLimits) + + meanTimeProfile <- plotMeanTimeProfile( + simulatedData, + observedData = observedData, + lloqData = lloqData, + metaData = metaData, + dataMapping = dataMapping, + plotConfiguration = NULL + ) + + meanTimeProfileLog <- tlf::setYAxis( + meanTimeProfile, + scale = tlf::Scaling$log, + limits = yAxisLimits, + ticks = yAxisTicks + ) + return(meanTimeProfileLog) } #' @title plotPopulationTimeProfile @@ -564,7 +620,6 @@ plotMeanTimeProfile <- function(simulatedData, #' @return ggplot object of time profile for mean model workflow #' @export #' @import tlf -#' @import ggplot2 plotPopulationTimeProfile <- function(simulatedData, observedData = NULL, lloqData = NULL, @@ -572,63 +627,112 @@ plotPopulationTimeProfile <- function(simulatedData, metaData = NULL, plotConfiguration = NULL) { - # metaData needs to be transfered to ymin and ymax + simulatedData <- removeMissingValues(simulatedData, dataMapping$y) + simulatedData <- removeMissingValues(simulatedData, dataMapping$ymin) + simulatedData <- removeMissingValues(simulatedData, dataMapping$ymax) + observedData <- removeMissingValues(observedData, dataMapping$y) + lloqData <- removeMissingValues(lloqData, dataMapping$y) + + # metaData needs to be transferred to ymin and ymax # so that y label shows dimension [unit] by default metaData$x <- metaData$Time metaData$ymin <- metaData$Concentration metaData$ymax <- metaData$Concentration + simulatedDataMapping <- tlf::TimeProfileDataMapping$new( + x = dataMapping$x, + y = dataMapping$y, + ymin = dataMapping$ymin, + ymax = dataMapping$ymax, + group = dataMapping$group + ) + observedDataMapping <- tlf::ObservedDataMapping$new( + x = dataMapping$x, + y = dataMapping$y, + group = dataMapping$group + ) + plotConfiguration <- plotConfiguration %||% TimeProfilePlotConfiguration$new( data = simulatedData, metaData = metaData, - dataMapping = TimeProfileDataMapping$new(x = "x", ymin = "ymin", ymax = "ymax") + dataMapping = simulatedDataMapping ) - plotConfiguration <- updatePlotConfigurationTimeTicks(simulatedData, metaData, dataMapping, plotConfiguration) + plotConfiguration <- updatePlotConfigurationTimeTicks(simulatedData, metaData, simulatedDataMapping, plotConfiguration) - timeProfilePlot <- tlf::addRibbon( - x = simulatedData$Time, - ymin = simulatedData$lowPerc, - ymax = simulatedData$highPerc, + timeProfilePlot <- tlf::plotTimeProfile( + data = simulatedData, metaData = metaData, - caption = simulatedData$legendRange, + dataMapping = simulatedDataMapping, + observedData = rbind.data.frame(observedData, lloqData), + observedDataMapping = observedDataMapping, plotConfiguration = plotConfiguration ) - timeProfilePlot <- tlf::addLine( - x = simulatedData$Time, - y = simulatedData$median, - caption = simulatedData$legendMedian, - plotConfiguration = plotConfiguration, - plotObject = timeProfilePlot - ) - timeProfilePlot <- tlf::addLine( - x = simulatedData$Time, - y = simulatedData$mean, - caption = simulatedData$legendMean, - plotConfiguration = plotConfiguration, - plotObject = timeProfilePlot - ) - if (!isEmpty(observedData)) { - timeProfilePlot <- tlf::addScatter( - data = observedData, - metaData = metaData, - dataMapping = dataMapping, - plotConfiguration = plotConfiguration, - plotObject = timeProfilePlot - ) + + return(timeProfilePlot) +} + +#' @title plotPopulationTimeProfileLog +#' @description Plot time profile for mean model workflow +#' @param simulatedData data.frame of simulated data +#' @param observedData data.frame of observed data +#' @param lloqData data.frame of lloq data +#' @param metaData meta data on `data` +#' @param dataMapping A list mapping `x`, `y` and `group` from datasets +#' @param plotConfiguration `PlotConfiguration` class object from `tlf` library +#' @return ggplot object of time profile for mean model workflow +#' @export +#' @import tlf +plotPopulationTimeProfileLog <- function(simulatedData, + observedData = NULL, + lloqData = NULL, + metaData = NULL, + dataMapping = NULL, + plotConfiguration = NULL) { + # Remove 0 values from simulated and observed data + # TODO: use dplyr to refactor the selection + simulatedData <- removeNegativeValues(simulatedData, dataMapping$y) + simulatedData <- removeNegativeValues(simulatedData, dataMapping$ymin) + simulatedData <- removeNegativeValues(simulatedData, dataMapping$ymax) + observedData <- removeNegativeValues(observedData, dataMapping$y) + lloqData <- removeNegativeValues(lloqData, dataMapping$y) + + logObservedValues <- NULL + logLLOQValues <- NULL + if(!isEmpty(observedData)){ + logObservedValues <- observedData[, dataMapping$y] } - if (!isEmpty(lloqData)) { - timeProfilePlot <- tlf::addLine( - data = lloqData, - metaData = metaData, - dataMapping = dataMapping, - plotConfiguration = plotConfiguration, - plotObject = timeProfilePlot - ) + if(!isEmpty(lloqData)){ + logLLOQValues <- lloqData[, dataMapping$y] } - timeProfilePlot <- tlf::setLegendPosition(plotObject = timeProfilePlot, position = reDefaultLegendPosition) + # Get the nice auto scaling of the log data + yAxisLimits <- autoAxesLimits(c( + simulatedData[, dataMapping$y], + simulatedData[, dataMapping$ymin], + simulatedData[, dataMapping$ymax], + logObservedValues, + logLLOQValues + ), + scale = "log" + ) + yAxisTicks <- autoAxesTicksFromLimits(yAxisLimits) - return(timeProfilePlot) + populationTimeProfile <- plotPopulationTimeProfile( + simulatedData, + observedData = observedData, + lloqData = lloqData, + metaData = metaData, + dataMapping = dataMapping, + plotConfiguration = NULL + ) + + populationTimeProfile <- tlf::setYAxis( + populationTimeProfile, + scale = tlf::Scaling$log, + limits = yAxisLimits, + ticks = yAxisTicks + ) + return(populationTimeProfile) } #' @title getSimulationTimeRanges @@ -849,13 +953,6 @@ getTimeProfilePlotResults <- function(workflowType, timeRange, simulatedData, ob selectedObservedData <- observedData[observedData$Path %in% selectedPaths, ] selectedLloqData <- lloqData[lloqData$Path %in% selectedPaths, ] - if (nrow(selectedObservedData) == 0) { - selectedObservedData <- NULL - } - if (nrow(selectedLloqData) == 0) { - selectedLloqData <- NULL - } - timeProfileMetaData <- list( "Time" = list(dimension = "Time", unit = structureSet$simulationSet$timeUnit), "Concentration" = list(dimension = selectedDimension, unit = unit) @@ -870,6 +967,14 @@ getTimeProfilePlotResults <- function(workflowType, timeRange, simulatedData, ob dataMapping = timeProfileMapping, plotConfiguration = settings$plotConfigurations[["timeProfile"]] ) + timeProfilePlotLog <- plotMeanTimeProfileLog( + simulatedData = selectedSimulatedData, + observedData = selectedObservedData, + lloqData = selectedLloqData, + metaData = timeProfileMetaData, + dataMapping = timeProfileMapping, + plotConfiguration = settings$plotConfigurations[["timeProfileLog"]] + ) } if (workflowType %in% "population") { timeProfilePlot <- plotPopulationTimeProfile( @@ -880,6 +985,14 @@ getTimeProfilePlotResults <- function(workflowType, timeRange, simulatedData, ob dataMapping = timeProfileMapping, plotConfiguration = settings$plotConfigurations[["timeProfile"]] ) + timeProfilePlotLog <- plotPopulationTimeProfileLog( + simulatedData = selectedSimulatedData, + observedData = selectedObservedData, + lloqData = selectedLloqData, + metaData = timeProfileMetaData, + dataMapping = timeProfileMapping, + plotConfiguration = settings$plotConfigurations[["timeProfileLog"]] + ) } timeProfilePlotLog <- tlf::setYAxis(plotObject = timeProfilePlot, scale = tlf::Scaling$log) @@ -983,7 +1096,7 @@ getResidualsPlotResults <- function(timeRange, residualsData, metaDataFrame, str ) goodnessOfFitPlots[[paste0("obsVsPred-", selectedDimension)]] <- obsVsPredPlot - goodnessOfFitCaptions[[paste0("obsVsPred-", selectedDimension)]] <- getGoodnessOfFitCaptions(structureSet, "obsVsPred", "linear") + goodnessOfFitCaptions[[paste0("obsVsPred-", selectedDimension)]] <- getGoodnessOfFitCaptions(structureSet, "obsVsPred", "linear", settings) # TODO: update after tlf is robust enough when 0 is in log plots (tlf issue #369) selectedLogData <- selectedResidualsData$Simulated > 0 & selectedResidualsData$Observed > 0 @@ -1020,7 +1133,7 @@ getResidualsPlotResults <- function(timeRange, residualsData, metaDataFrame, str ) goodnessOfFitPlots[[paste0("obsVsPredLog-", selectedDimension)]] <- obsVsPredPlotLog - goodnessOfFitCaptions[[paste0("obsVsPredLog-", selectedDimension)]] <- getGoodnessOfFitCaptions(structureSet, "obsVsPred", "logarithmic") + goodnessOfFitCaptions[[paste0("obsVsPredLog-", selectedDimension)]] <- getGoodnessOfFitCaptions(structureSet, "obsVsPred", "logarithmic", settings) } goodnessOfFitPlots[[paste0("resVsPred-", selectedDimension)]] <- tlf::plotResVsPred( @@ -1033,7 +1146,7 @@ getResidualsPlotResults <- function(timeRange, residualsData, metaDataFrame, str ), plotConfiguration = settings$plotConfigurations[["resVsPred"]] ) - goodnessOfFitCaptions[[paste0("resVsPred-", selectedDimension)]] <- getGoodnessOfFitCaptions(structureSet, "resVsPred", residualScale) + goodnessOfFitCaptions[[paste0("resVsPred-", selectedDimension)]] <- getGoodnessOfFitCaptions(structureSet, "resVsPred", residualScale, settings) } residualsMetaData <- list( diff --git a/R/utilities-observed-data.R b/R/utilities-observed-data.R index d99e8b19..6ccdb4e6 100644 --- a/R/utilities-observed-data.R +++ b/R/utilities-observed-data.R @@ -252,10 +252,10 @@ loadObservedDataFromSimulationSet <- function(simulationSet) { #' @param data A data.frame #' @param dataMapping A list mapping the variable of data #' @param molWeight Molar weight for unit conversion of dependent variable -#' @param timeUnit time unit for unit conversion of time +#' @param structureSet A `SimulationStructure` object #' @return list of data and lloq data.frames #' @keywords internal -getObservedDataFromOutput <- function(output, data, dataMapping, molWeight, timeUnit) { +getObservedDataFromOutput <- function(output, data, dataMapping, molWeight, structureSet) { # If no observed data nor data selected, return empty dataset if (isEmpty(data)) { return() @@ -289,9 +289,17 @@ getObservedDataFromOutput <- function(output, data, dataMapping, molWeight, time } } outputData <- data.frame( - "Time" = ospsuite::toUnit("Time", data[selectedRows, dataMapping$time], timeUnit), + "Time" = ospsuite::toUnit( + "Time", + data[selectedRows, dataMapping$time], + structureSet$simulationSet$timeUnit + ), "Concentration" = outputConcentration, - "Legend" = paste0("Observed data ", output$dataDisplayName), + "Legend" = captions$plotGoF$observedLegend( + simulationSetName = structureSet$simulationSet$simulationSetName, + descriptor = structureSet$simulationSetDescriptor, + pathName = output$dataDisplayName + ), "Path" = output$path ) if (isEmpty(dataMapping$lloq)) { @@ -314,9 +322,17 @@ getObservedDataFromOutput <- function(output, data, dataMapping, molWeight, time } } lloqOutput <- data.frame( - "Time" = ospsuite::toUnit("Time", data[selectedRows, dataMapping$time], timeUnit), + "Time" = ospsuite::toUnit( + "Time", + data[selectedRows, dataMapping$time], + structureSet$simulationSet$timeUnit + ), "Concentration" = lloqConcentration, - "Legend" = "LLOQ", + "Legend" = captions$plotGoF$lloqLegend( + simulationSetName = structureSet$simulationSet$simulationSetName, + descriptor = structureSet$simulationSetDescriptor, + pathName = output$dataDisplayName + ), "Path" = output$path ) return(list(data = outputData, lloq = lloqOutput)) diff --git a/R/utils.R b/R/utils.R index 7b2f6b73..b9305a5e 100644 --- a/R/utils.R +++ b/R/utils.R @@ -17,6 +17,44 @@ calculateResiduals <- function(simulatedData, observedData, residualScale) { } } +# TODO: add these functions to tlf + +#' @title geomean +#' @description +#' Calculate the geometric mean +#' @param x values +#' @param na.rm logical defining removal of `NA` values +#' @return Geometric mean +#' @export +geomean <- function(x, na.rm = TRUE) { + logX <- log(x[x>0]) + exp(mean(logX, na.rm = na.rm)) +} + +#' @title geomean*sd +#' @description +#' Calculate the geometric mean * geometric SD +#' @param x values +#' @param na.rm logical defining removal of `NA` values +#' @return Geometric mean * geometric SD +#' @export +`geomean*sd` <- function(x, na.rm = TRUE) { + logX <- log(x[x>0]) + exp(mean(logX, na.rm = na.rm)+stats::sd(logX, na.rm = na.rm)) +} + +#' @title geomean/sd +#' @description +#' Calculate the geometric mean / geometric SD +#' @param x values +#' @param na.rm logical defining removal of `NA` values +#' @return Geometric mean / geometric SD +#' @export +`geomean/sd` <- function(x, na.rm = TRUE) { + logX <- log(x[x>0]) + exp(mean(logX, na.rm = na.rm)-stats::sd(logX, na.rm = na.rm)) +} + #' @title calculateGeometricErrorRange #' @param values Numeric values of the geometric mean #' @param errorValues Numeric values of the geometric error @@ -204,6 +242,9 @@ replaceInfWithNA <- function(data) { #' @return filtered data.frame #' @keywords internal removeMissingValues <- function(data, dataMapping = NULL) { + if(isEmpty(data)){ + return(data) + } data[, dataMapping] <- replaceInfWithNA(data[, dataMapping]) naData <- is.na(data[, dataMapping]) Nna <- sum(naData) @@ -215,6 +256,25 @@ removeMissingValues <- function(data, dataMapping = NULL) { return(data) } +#' @title removeNegativeValues +#' @param data data.frame +#' @param dataMapping name of variable on which the missing values ar checked +#' @return filtered data.frame +#' @keywords internal +removeNegativeValues <- function(data, dataMapping = NULL) { + if(isEmpty(data)){ + return(data) + } + negativeData <- data[, dataMapping] <= 0 + Nnegative <- sum(negativeData, na.rm = TRUE) + data <- data[!negativeData, ] + + if (Nnegative > 0) { + logDebug(paste0(Nnegative, " values from variable '", dataMapping, "' were negative and removed from the analysis")) + } + return(data) +} + #' @title getPKParametersInOutput #' @param output Output object #' @return Names of pkParameters in `output` diff --git a/man/AllAvailableTasks.Rd b/man/AllAvailableTasks.Rd index f53057ec..630d7b73 100644 --- a/man/AllAvailableTasks.Rd +++ b/man/AllAvailableTasks.Rd @@ -26,7 +26,8 @@ Other enum helpers: \code{\link{PopulationWorkflowTypes}}, \code{\link{ResidualScales}}, \code{\link{StandardPlotTasks}}, -\code{\link{StandardSimulationTasks}} +\code{\link{StandardSimulationTasks}}, +\code{\link{StatisticsTypes}} } \concept{enum helpers} \keyword{datasets} diff --git a/man/ApplicationRanges.Rd b/man/ApplicationRanges.Rd index 1559facc..5d25d26f 100644 --- a/man/ApplicationRanges.Rd +++ b/man/ApplicationRanges.Rd @@ -26,7 +26,8 @@ Other enum helpers: \code{\link{PopulationWorkflowTypes}}, \code{\link{ResidualScales}}, \code{\link{StandardPlotTasks}}, -\code{\link{StandardSimulationTasks}} +\code{\link{StandardSimulationTasks}}, +\code{\link{StatisticsTypes}} } \concept{enum helpers} \keyword{datasets} diff --git a/man/DataSelectionKeys.Rd b/man/DataSelectionKeys.Rd index 13fbf6ca..f7136ecf 100644 --- a/man/DataSelectionKeys.Rd +++ b/man/DataSelectionKeys.Rd @@ -26,7 +26,8 @@ Other enum helpers: \code{\link{PopulationWorkflowTypes}}, \code{\link{ResidualScales}}, \code{\link{StandardPlotTasks}}, -\code{\link{StandardSimulationTasks}} +\code{\link{StandardSimulationTasks}}, +\code{\link{StatisticsTypes}} } \concept{enum helpers} \keyword{datasets} diff --git a/man/GofTaskSettings.Rd b/man/GofTaskSettings.Rd index 156db8fe..b4e588d3 100644 --- a/man/GofTaskSettings.Rd +++ b/man/GofTaskSettings.Rd @@ -5,6 +5,37 @@ \title{GofTaskSettings} \description{ R6 class defining properties of time profiles and residuals plot task settings +} +\examples{ + +## ------------------------------------------------ +## Method `GofTaskSettings$setStatistics` +## ------------------------------------------------ + +\dontrun{ +# Set the statistics as geometric mean +workflow$plotTimeProfilesAndResiduals$settings$setStatistics( +statisticsType = StatisticsTypes$`Geometric mean` +) + +# Set the legend caption displayed for range +workflow$plotTimeProfilesAndResiduals$settings$setStatistics( +statisticsType = StatisticsTypes$`Geometric mean` +rangeCaption = "90\% population range" +) + +} + + +## ------------------------------------------------ +## Method `GofTaskSettings$getStatistics` +## ------------------------------------------------ + +\dontrun{ +# Get the statistics of time profiles task +workflow$plotTimeProfilesAndResiduals$settings$getStatistics() +} + } \keyword{internal} \section{Super class}{ @@ -31,6 +62,8 @@ time profiles and residual plots when applicable} \subsection{Public methods}{ \itemize{ \item \href{#method-GofTaskSettings-new}{\code{GofTaskSettings$new()}} +\item \href{#method-GofTaskSettings-setStatistics}{\code{GofTaskSettings$setStatistics()}} +\item \href{#method-GofTaskSettings-getStatistics}{\code{GofTaskSettings$getStatistics()}} \item \href{#method-GofTaskSettings-clone}{\code{GofTaskSettings$clone()}} } } @@ -42,7 +75,8 @@ Create a `GofTaskSettings` object \subsection{Usage}{ \if{html}{\out{
}}\preformatted{GofTaskSettings$new( taskName = AllAvailableTasks$plotTimeProfilesAndResiduals, - outputSelections = NULL + outputSelections = NULL, + statisticsType = NULL )}\if{html}{\out{
}} } @@ -52,12 +86,91 @@ Create a `GofTaskSettings` object \item{\code{taskName}}{name of the task using the settings} \item{\code{outputSelections}}{subset of simulationSet outputs to be used in GoF plot} + +\item{\code{statisticsType}}{Statistics summarizing time profile simulated data} } \if{html}{\out{}} } \subsection{Returns}{ A new `GofTaskSettings` object } +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-GofTaskSettings-setStatistics}{}}} +\subsection{Method \code{setStatistics()}}{ +Set statistics used in population time profiles and residuals plots +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{GofTaskSettings$setStatistics( + statisticsType = NULL, + y = NULL, + ymin = NULL, + ymax = NULL, + yCaption = NULL, + rangeCaption = NULL +)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{statisticsType}}{Name of statistics type as defined in enum `StatisticsTypes`} + +\item{\code{y}}{Function or function name for middle values statistics} + +\item{\code{ymin}}{Function or function name for min values statistics} + +\item{\code{ymax}}{Function or function name for max values statistics} + +\item{\code{yCaption}}{Legend caption for middle values statistics} + +\item{\code{rangeCaption}}{Legend caption for range values statistics} +} +\if{html}{\out{
}} +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ +# Set the statistics as geometric mean +workflow$plotTimeProfilesAndResiduals$settings$setStatistics( +statisticsType = StatisticsTypes$`Geometric mean` +) + +# Set the legend caption displayed for range +workflow$plotTimeProfilesAndResiduals$settings$setStatistics( +statisticsType = StatisticsTypes$`Geometric mean` +rangeCaption = "90\% population range" +) + +} + +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-GofTaskSettings-getStatistics}{}}} +\subsection{Method \code{getStatistics()}}{ +Get statistics used in population time profiles and residuals plots +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{GofTaskSettings$getStatistics()}\if{html}{\out{
}} +} + +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ +# Get the statistics of time profiles task +workflow$plotTimeProfilesAndResiduals$settings$getStatistics() +} + +} +\if{html}{\out{
}} + +} + } \if{html}{\out{
}} \if{html}{\out{}} diff --git a/man/PopulationWorkflowTypes.Rd b/man/PopulationWorkflowTypes.Rd index 64e3650d..fedac756 100644 --- a/man/PopulationWorkflowTypes.Rd +++ b/man/PopulationWorkflowTypes.Rd @@ -26,7 +26,8 @@ Other enum helpers: \code{\link{DataSelectionKeys}}, \code{\link{ResidualScales}}, \code{\link{StandardPlotTasks}}, -\code{\link{StandardSimulationTasks}} +\code{\link{StandardSimulationTasks}}, +\code{\link{StatisticsTypes}} } \concept{enum helpers} \keyword{datasets} diff --git a/man/ResidualScales.Rd b/man/ResidualScales.Rd index 0137f517..96b1ddf1 100644 --- a/man/ResidualScales.Rd +++ b/man/ResidualScales.Rd @@ -26,7 +26,8 @@ Other enum helpers: \code{\link{DataSelectionKeys}}, \code{\link{PopulationWorkflowTypes}}, \code{\link{StandardPlotTasks}}, -\code{\link{StandardSimulationTasks}} +\code{\link{StandardSimulationTasks}}, +\code{\link{StatisticsTypes}} } \concept{enum helpers} \keyword{datasets} diff --git a/man/StandardPlotTasks.Rd b/man/StandardPlotTasks.Rd index 83e3ce0c..1f641a13 100644 --- a/man/StandardPlotTasks.Rd +++ b/man/StandardPlotTasks.Rd @@ -26,7 +26,8 @@ Other enum helpers: \code{\link{DataSelectionKeys}}, \code{\link{PopulationWorkflowTypes}}, \code{\link{ResidualScales}}, -\code{\link{StandardSimulationTasks}} +\code{\link{StandardSimulationTasks}}, +\code{\link{StatisticsTypes}} } \concept{enum helpers} \keyword{datasets} diff --git a/man/StandardSimulationTasks.Rd b/man/StandardSimulationTasks.Rd index 93278923..463bd6ec 100644 --- a/man/StandardSimulationTasks.Rd +++ b/man/StandardSimulationTasks.Rd @@ -26,7 +26,8 @@ Other enum helpers: \code{\link{DataSelectionKeys}}, \code{\link{PopulationWorkflowTypes}}, \code{\link{ResidualScales}}, -\code{\link{StandardPlotTasks}} +\code{\link{StandardPlotTasks}}, +\code{\link{StatisticsTypes}} } \concept{enum helpers} \keyword{datasets} diff --git a/man/StatisticsTypes.Rd b/man/StatisticsTypes.Rd new file mode 100644 index 00000000..c22de800 --- /dev/null +++ b/man/StatisticsTypes.Rd @@ -0,0 +1,39 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/reportingengine-env.R +\docType{data} +\name{StatisticsTypes} +\alias{StatisticsTypes} +\title{StatisticsTypes} +\format{ +An object of class \code{list} of length 5. +} +\usage{ +StatisticsTypes +} +\description{ +List of available statistic types summarizing data for time profile plots +\itemize{ +\item `"2.5th-97.5th Percentiles"` summarizes data using median, 2.5th and 97.5th percentiles +\item `"5th-95th Percentiles"` summarizes data using median, 5th and 95th percentiles +\item `"10th-90th Percentiles"` summarizes data using median, 10th and 90th percentiles +\item `"Geometric mean"` summarizes data using geometric mean and mean */ geometric standard deviation +\item `"Arithmetic mean"` summarizes data using arithmetic mean and mean +/- standard deviation +} +} +\examples{ +dontrun{ +getStatisticsFromType(StatisticsTypes) +} +} +\seealso{ +Other enum helpers: +\code{\link{AllAvailableTasks}}, +\code{\link{ApplicationRanges}}, +\code{\link{DataSelectionKeys}}, +\code{\link{PopulationWorkflowTypes}}, +\code{\link{ResidualScales}}, +\code{\link{StandardPlotTasks}}, +\code{\link{StandardSimulationTasks}} +} +\concept{enum helpers} +\keyword{datasets} diff --git a/man/geomean-slash-sd.Rd b/man/geomean-slash-sd.Rd new file mode 100644 index 00000000..de3e13c3 --- /dev/null +++ b/man/geomean-slash-sd.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{geomean/sd} +\alias{geomean/sd} +\title{geomean/sd} +\usage{ +`geomean/sd`(x, na.rm = TRUE) +} +\arguments{ +\item{x}{values} + +\item{na.rm}{logical defining removal of `NA` values} +} +\value{ +Geometric mean / geometric SD +} +\description{ +Calculate the geometric mean / geometric SD +} diff --git a/man/geomean-times-sd.Rd b/man/geomean-times-sd.Rd new file mode 100644 index 00000000..34e080d6 --- /dev/null +++ b/man/geomean-times-sd.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{geomean*sd} +\alias{geomean*sd} +\title{geomean*sd} +\usage{ +`geomean*sd`(x, na.rm = TRUE) +} +\arguments{ +\item{x}{values} + +\item{na.rm}{logical defining removal of `NA` values} +} +\value{ +Geometric mean * geometric SD +} +\description{ +Calculate the geometric mean * geometric SD +} diff --git a/man/geomean.Rd b/man/geomean.Rd new file mode 100644 index 00000000..5bd7b77d --- /dev/null +++ b/man/geomean.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{geomean} +\alias{geomean} +\title{geomean} +\usage{ +geomean(x, na.rm = TRUE) +} +\arguments{ +\item{x}{values} + +\item{na.rm}{logical defining removal of `NA` values} +} +\value{ +Geometric mean +} +\description{ +Calculate the geometric mean +} diff --git a/man/getObservedDataFromOutput.Rd b/man/getObservedDataFromOutput.Rd index 884c8b50..5a13202e 100644 --- a/man/getObservedDataFromOutput.Rd +++ b/man/getObservedDataFromOutput.Rd @@ -4,7 +4,7 @@ \alias{getObservedDataFromOutput} \title{getObservedDataFromOutput} \usage{ -getObservedDataFromOutput(output, data, dataMapping, molWeight, timeUnit) +getObservedDataFromOutput(output, data, dataMapping, molWeight, structureSet) } \arguments{ \item{output}{An `Output` object} @@ -15,7 +15,7 @@ getObservedDataFromOutput(output, data, dataMapping, molWeight, timeUnit) \item{molWeight}{Molar weight for unit conversion of dependent variable} -\item{timeUnit}{time unit for unit conversion of time} +\item{structureSet}{A `SimulationStructure` object} } \value{ list of data and lloq data.frames diff --git a/man/getPopulationResultsFromOutput.Rd b/man/getPopulationResultsFromOutput.Rd index 0e550e6f..3eca9696 100644 --- a/man/getPopulationResultsFromOutput.Rd +++ b/man/getPopulationResultsFromOutput.Rd @@ -9,7 +9,7 @@ getPopulationResultsFromOutput( output, simulationQuantity, molWeight, - simulationSet, + structureSet, settings = NULL ) } @@ -22,7 +22,7 @@ getPopulationResultsFromOutput( \item{molWeight}{Molar weight for unit conversion of dependent variable} -\item{simulationSet}{`SimulationSet` object} +\item{structureSet}{`SimulationStructure` object} \item{settings}{TaskSetting object} } diff --git a/man/getSimulatedResultsFromOutput.Rd b/man/getSimulatedResultsFromOutput.Rd index 7eec1896..8c86253b 100644 --- a/man/getSimulatedResultsFromOutput.Rd +++ b/man/getSimulatedResultsFromOutput.Rd @@ -9,7 +9,7 @@ getSimulatedResultsFromOutput( output, simulationQuantity, molWeight, - simulationSet + structureSet ) } \arguments{ @@ -21,7 +21,7 @@ getSimulatedResultsFromOutput( \item{molWeight}{Molar weight for unit conversion of dependent variable} -\item{simulationSet}{`SimulationSet` object} +\item{structureSet}{`SimulationStructure` object} } \value{ list of data and metaData diff --git a/man/getStatisticsFromType.Rd b/man/getStatisticsFromType.Rd new file mode 100644 index 00000000..16893f48 --- /dev/null +++ b/man/getStatisticsFromType.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/reportingengine-env.R +\name{getStatisticsFromType} +\alias{getStatisticsFromType} +\title{getStatisticsFromType} +\usage{ +getStatisticsFromType(statisticsType) +} +\arguments{ +\item{statisticsType}{Statistics summarizing time profile simulated data +as defined by helper enum `StatisticsType`} +} +\value{ +A list including `y`, `ymin` and `ymax` summary statistics as well as their `caption` +} +\description{ +Get statistics +} +\examples{ +dontrun{ +workflow$plotTime +} +} diff --git a/man/pkDictionaryQualificationOSP.Rd b/man/pkDictionaryQualificationOSP.Rd index 90723020..829c476e 100644 --- a/man/pkDictionaryQualificationOSP.Rd +++ b/man/pkDictionaryQualificationOSP.Rd @@ -5,7 +5,7 @@ \alias{pkDictionaryQualificationOSP} \title{Dictionary for `ospsuite` PK parameters defined by Configuration Plan} \format{ -An object of class \code{list} of length 43. +An object of class \code{list} of length 33. } \usage{ pkDictionaryQualificationOSP diff --git a/man/plotMeanTimeProfile.Rd b/man/plotMeanTimeProfile.Rd index ca2fa126..8fdfd76e 100644 --- a/man/plotMeanTimeProfile.Rd +++ b/man/plotMeanTimeProfile.Rd @@ -22,7 +22,7 @@ plotMeanTimeProfile( \item{metaData}{meta data on `data`} -\item{dataMapping}{`XYGDataMapping` R6 class object from `tlf` library} +\item{dataMapping}{A list mapping `x`, `y` and `group` from datasets} \item{plotConfiguration}{`PlotConfiguration` class object from `tlf` library} } diff --git a/man/plotMeanTimeProfileLog.Rd b/man/plotMeanTimeProfileLog.Rd new file mode 100644 index 00000000..27ab8701 --- /dev/null +++ b/man/plotMeanTimeProfileLog.Rd @@ -0,0 +1,34 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utilities-goodness-of-fit.R +\name{plotMeanTimeProfileLog} +\alias{plotMeanTimeProfileLog} +\title{plotMeanTimeProfileLog} +\usage{ +plotMeanTimeProfileLog( + simulatedData, + observedData = NULL, + lloqData = NULL, + metaData = NULL, + dataMapping = NULL, + plotConfiguration = NULL +) +} +\arguments{ +\item{simulatedData}{data.frame of simulated data} + +\item{observedData}{data.frame of observed data} + +\item{lloqData}{data.frame of lloq data} + +\item{metaData}{meta data on `data`} + +\item{dataMapping}{A list mapping `x`, `y` and `group` from datasets} + +\item{plotConfiguration}{`PlotConfiguration` class object from `tlf` library} +} +\value{ +ggplot object of time profile for mean model workflow +} +\description{ +Plot time profile for mean model workflow +} diff --git a/man/plotPopulationTimeProfileLog.Rd b/man/plotPopulationTimeProfileLog.Rd new file mode 100644 index 00000000..c9768817 --- /dev/null +++ b/man/plotPopulationTimeProfileLog.Rd @@ -0,0 +1,34 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utilities-goodness-of-fit.R +\name{plotPopulationTimeProfileLog} +\alias{plotPopulationTimeProfileLog} +\title{plotPopulationTimeProfileLog} +\usage{ +plotPopulationTimeProfileLog( + simulatedData, + observedData = NULL, + lloqData = NULL, + metaData = NULL, + dataMapping = NULL, + plotConfiguration = NULL +) +} +\arguments{ +\item{simulatedData}{data.frame of simulated data} + +\item{observedData}{data.frame of observed data} + +\item{lloqData}{data.frame of lloq data} + +\item{metaData}{meta data on `data`} + +\item{dataMapping}{A list mapping `x`, `y` and `group` from datasets} + +\item{plotConfiguration}{`PlotConfiguration` class object from `tlf` library} +} +\value{ +ggplot object of time profile for mean model workflow +} +\description{ +Plot time profile for mean model workflow +} diff --git a/man/removeNegativeValues.Rd b/man/removeNegativeValues.Rd new file mode 100644 index 00000000..5ac0f370 --- /dev/null +++ b/man/removeNegativeValues.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{removeNegativeValues} +\alias{removeNegativeValues} +\title{removeNegativeValues} +\usage{ +removeNegativeValues(data, dataMapping = NULL) +} +\arguments{ +\item{data}{data.frame} + +\item{dataMapping}{name of variable on which the missing values ar checked} +} +\value{ +filtered data.frame +} +\description{ +removeNegativeValues +} +\keyword{internal} diff --git a/man/setDefaultTimeProfileStatistics.Rd b/man/setDefaultTimeProfileStatistics.Rd new file mode 100644 index 00000000..6a58e883 --- /dev/null +++ b/man/setDefaultTimeProfileStatistics.Rd @@ -0,0 +1,42 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/reportingengine-env.R +\name{setDefaultTimeProfileStatistics} +\alias{setDefaultTimeProfileStatistics} +\title{setDefaultTimeProfileStatistics} +\usage{ +setDefaultTimeProfileStatistics( + statisticsType = NULL, + y = NULL, + ymin = NULL, + ymax = NULL, + yCaption = NULL, + rangeCaption = NULL +) +} +\arguments{ +\item{statisticsType}{Name of statistics type as defined in enum `StatisticsTypes`} + +\item{y}{Function or function name for middle values statistics} + +\item{ymin}{Function or function name for min values statistics} + +\item{ymax}{Function or function name for max values statistics} + +\item{yCaption}{Legend caption for middle values statistics} + +\item{rangeCaption}{Legend caption for range values statistics} +} +\description{ +Set default statistics used in population time profiles and residuals plots +} +\examples{ +\dontrun{ +# Set the default statistics as geometric mean +setDefaultTimeProfileStatistics(statisticsType = StatisticsTypes$`Geometric mean`) + +# Set the default legend caption displayed for range +setDefaultTimeProfileStatistics(rangeCaption = "90\% population range") + +} + +}