#' @include LongTableDataMapper-class.R
NULL
## =====================================
## LongTableDataMapper Accessors Methods
## -------------------------------------
## ---------------------
## ---- all slot helpers
#' Method to subset the rawdata with the corresponding dimensions "dimDataMap"
#' method.
#'
#' @param x `LongTableDataMapper` or inheriting class.
#' @param key `logical(1)` Should the returned value be keyed by the 'id_columns'
#' item of the dimDataMap? Ignored when dim is "meta".
#' @param dim `character(1)` Which dimension should rawdata to subset for?
#' Options are "row", "col" and "meta", corresponding to the associated
#' slots of the `LongTableDataMapper`.
#'
#' @importFrom checkmate assertClass assertLogical
#' @importFrom methods getPackageName
#' @noRd
#' @keywords internal
.get_dimData <- function(x, key, dim=c("row", "col", "meta")) {
# Input validation
assertClass(x, "LongTableDataMapper")
assertLogical(key)
# Determine which slot and accessor function to use
dim <- match.arg(dim)
dimSlot <- paste0(dim, "DataMap")
dimFun <- get(dimSlot)
# Get method name to simplify debugging from S4 classes
funContext <- paste0("\n[", getPackageName(), "::", dimSlot, ",",
class(x)[1], "-method\n\t")
.dimDataMap <- dimFun(x)
# Ensure required data is present
if (length(unlist(.dimDataMap)) < 1) stop(.errorMsg(funContext,
"The ", dimSlot, " slot must contain valid data!"))
return(.get_dimDataFromMap(x=x, key=(key && dim != "meta"),
dataMap=.dimDataMap, funContext=funContext))
}
#' Method to subset the rawdata with the corresponding dimensions "dimDataMap"
#' method.
#'
#' @param x `LongTableDataMapper` or inheriting class.
#' @param dataMap `list` The map of a `LongTableDataMapper` dimension, as
#' returned by the '*DataMap' methods. Can also be used with a single assay
#' from the `assayMap` method, but not the entire list of assays.
#' @param key `logical(1)` Should the returned value be keyed by the 'id_columns'
#' item of the dimDataMap? Default is `TRUE`.
#' @param rename `logical(1)` Should columns be renamed from their value to
#' their name, if the item has a name in the `dataMap`. Default is `TRUE`.
#' @param funContext `character(1)` Contextual information about the calling
#' function, for debugging. Users don't need to worry about this.
#'
#' @importFrom checkmate assertClass assertLogical assertList
#' @importFrom methods getPackageName
#' @importFrom data.table setkeyv
#' @noRd
#' @keywords internal
.get_dimDataFromMap <- function(x, dataMap, key=TRUE, rename=TRUE, funContext) {
if (missing(funContext))
funContext <- paste0("\n[", getPackageName(), "::.get_dimDataMap]\n\t")
# Input validation
checkmate::assertClass(x, "LongTableDataMapper")
checkmate::assertLogical(key)
checkmate::assertList(dataMap, types=c("character", "NULL"), max.len=2)
# Extract relevant data
.rawdata <- rawdata(x)
# Ensure required data is present
if (length(.rawdata) < 1) .error(funContext,
"The rawdata slot must contain valid data!")
hasDimDataCols <- unlist(dataMap) %in% colnames(.rawdata)
if (!all(hasDimDataCols)) .error(funContext, "Columns ",
.collapse(unlist(dataMap)[!hasDimDataCols]),
" are missing from rawdata!")
# Subset rawdata, optionally keying table and/or renaming columns
.dimData <- .rawdata[, .SD, .SDcols=unlist(dataMap)]
if (key) setkeyv(.dimData, dataMap$id_columns)
if (rename) {
old <- unlist(unname(dataMap))
new <- names(old)
if (!is.null(new)) {
names_idx <- new != "" & !is.na(new)
data.table::setnames(.dimData, old[names_idx], new[names_idx])
}
}
return(unique(.dimData))
}
## ---------------
## -- rawdata slot
#' @rdname LongTableDataMapper-accessors
#' @eval .docs_DataMapper_set_rawdata(class_=.local_class_3,
#' class1_='list')
setReplaceMethod('rawdata', signature=c(object='LongTableDataMapper',
value='list'), function(object, value) {
funContext <- .S4MethodContext('rawdata<-', class(object)[1],
class(value)[1])
rows <- unlist(rowDataMap(object))
cols <- unlist(colDataMap(object))
assays <- unlist(assayMap(object))
meta <- unlist(metadataMap(object))
## TODO:: Improve parsing here such that it only throws warnings if meta-
##>data columns are missing
mandatory <- c(rows, cols, assays, meta)
if (!length(mandatory) || !length(value)) {
object@rawdata <- value
} else if (length(mandatory) && !length(rawdata(object))) {
hasMandatory <- mandatory %in% colnames(value)
if (!all(hasMandatory)) {
stop(.errorMsg(funContext, "One or more map column is missing from value",
": ", paste0(mandatory[!hasMandatory], collapse=', '), '!'))
}
object@rawdata <- value
} else {
stop(.errorMsg(funContext, "In order to assign to the rawdata slot of ",
"a LongTableDataMapper, either all the map slots must be ",
"empty or the rawdata slot must be an empty list!"))
}
return(object)
})
## --------------------
## ---- rowDataMap slot
##
## -- rowDataMap
.docs_LongTableDataMapper_get_dimDataMap <- function(...) .parseToRoxygen(
"
@details
__{dim_}DataMap__: `list` of two `character` vectors, the first are the
columns required to uniquely identify each row of a `{class_}` and the
second any additional {dim_}-level metadata. If the character vectors
have names, the resulting columns are automatically renamed to the
item name of the specified column.
@examples
{dim_}DataMap({data_})
@md
@aliases {dim_}DataMap,{class_}-method
@exportMethod {dim_}DataMap
",
...
)
#' @export
setGeneric('rowDataMap', function(object, ...) standardGeneric('rowDataMap'))
#' @rdname LongTableDataMapper-accessors
#' @eval
#' .docs_LongTableDataMapper_get_dimDataMap(dim_='row', class_=.local_class_3,
#' data_=.local_data_3)
setMethod('rowDataMap', signature(object='LongTableDataMapper'),
function(object) {
object@rowDataMap
})
#' @export
setGeneric('rowDataMap<-', function(object, ..., value)
standardGeneric('rowDataMap<-'))
.docs_LongTableDataMapper_set_dimDataMap <- function(...) .parseToRoxygen(
"
@details
__{dim_}DataMap<-__: Update the `@{dim_}DataMap` slot of a `{class_}` object,
returning an invisible NULL. Arguments:
- value: A `list` or `List` where the first item is the names of the
identifier columns -- columns needed to uniquely identify each row in
{dim_}Data -- and the second item is the metadata associated with those
the identifier columns, but not required to uniquely identify rows in
the object rowData.
@examples
{dim_}DataMap({data_}) <- list(c('{id_col_}'), c())
@md
@aliases rowDataMap<-,{class_},list-method {dim_}DataMap<-{class_},List-method
@exportMethod {dim_}DataMap<-
",
...
)
#' @rdname LongTableDataMapper-accessors
#' @eval
#' .docs_LongTableDataMapper_set_dimDataMap(dim_='row', class_=.local_class_3,
#' data_=.local_data_3, id_col_='treatmentid')
setReplaceMethod('rowDataMap', signature(object='LongTableDataMapper',
value='list_OR_List'), function(object, value) {
funContext <- '[CoreGx::`rowDataMap<-`,LongTableDataMapper-method]\n\t'
rawdataCols <- colnames(rawdata(object))
# -- Handle error conditions
if (length(value) > 2) {
stop(.errorMsg(funContext, 'Assignments to rowDataMap should be a list ',
'of length 2, where the first item is the name of the id columns ',
'and the second item is the name of the metadata columns which ',
'map to those id columns.'))
}
hasIDcols <- value[[1]] %in% rawdataCols
if (!all(hasIDcols) && length(rawdata(object))) {
stop(.errorMsg(funContext, 'One or more of the id columns specified ',
'in value[[1]] are not valid column names in the rawdata slot of ',
'this ', class(object)[1], ' object!'))
}
if (length(value) > 1 && length(value[[2]]) != 0 && length(rawdata(object))) {
hasMetaCols <- value[[2]] %in% rawdataCols
if (!all(hasMetaCols)) {
stop(.errorMsg(funContext, 'The follow metadata columns in value[[2]] ',
'are not present in rawdata(object): ',
.collapse(value[[2]][!hasMetaCols]), '!'))
}
hasOneToOneRelationship <-
value[[2]] %in% cardinality(rawdata(object), group=value[[1]])
if (!all(hasOneToOneRelationship)) {
stop(.errorMsg(funContext, 'The columns ',
.collapse(value[[2]][!hasOneToOneRelationship], ' do not have a ',
'1:1 relationship with the specified ID columns!')))
}
}
# -- Function body
object@rowDataMap <- value
return(object)
})
##
## -- rowData
#' Convenience method to subset the `rowData` out of the `rawdata` slot using
#' the assigned `rowDataMap` metadata.
#'
#' @param x `LongTableDataMapper` object with valid data in the `rawdata` and
#' `colDataMap` slots.
#' @param key `logical(1)` Should the table be keyed according to the
#' `id_columns` of the `rowDataMap` slot? This will sort the table in memory.
#' Default is TRUE.
#'
#' @return `data.table` The `rowData` as specified in the `rowDataMap` slot.
#'
#' @export
setMethod("rowData", signature("LongTableDataMapper"), function(x, key=TRUE) {
.get_dimData(x, key, dim="row")
})
## --------------------
## ---- colDataMap slot
##
## -- colDataMap
#' @export
setGeneric('colDataMap', function(object, ...) standardGeneric('colDataMap'))
#' @rdname LongTableDataMapper-accessors
#' @eval
#' .docs_LongTableDataMapper_get_dimDataMap(dim_='col', class_=.local_class_3,
#' data_=.local_data_3)
setMethod('colDataMap', signature(object='LongTableDataMapper'),
function(object) {
object@colDataMap
})
#' @export
setGeneric('colDataMap<-', function(object, ..., value) standardGeneric('colDataMap<-'))
#' @rdname LongTableDataMapper-accessors
#' @eval
#' .docs_LongTableDataMapper_set_dimDataMap(dim_='col', class_=.local_class_3,
#' data_=.local_data_3, id_col_='sampleid')
setReplaceMethod('colDataMap',
signature(object='LongTableDataMapper', value='list_OR_List'),
function(object, value) {
funContext <- '[CoreGx::`colDataMap<-`,LongTableDataMapper-method]\n\t'
rawdataCols <- colnames(rawdata(object))
# -- Handle error conditions
if (length(value) > 2 || !is.list(value)) {
.error(funContext, 'Assignments to colDataMap should be a list ',
'of length 2, where the first item is the name of the id columns ',
'and the second item is the name of the metadata columns which ',
'map to those id columns.')
}
hasIDcols <- value[[1]] %in% rawdataCols
if (!all(hasIDcols) && length(rawdata(object))) {
.error(funContext, 'One or more of the id columns specified ',
'in value[[1]] are not valid column names in the rawdata slot of ',
'this ', class(object)[1], ' object!')
}
if (length(value) > 1 && length(value[[2]]) != 0 &&
length(rawdata(object))) {
hasMetaCols <- value[[2]] %in% rawdataCols
if (!all(hasMetaCols)) {
.error(funContext,
'The follow metadata columns in value[[2]] ',
'are not present in rawdata(object): ',
.collapse(value[[2]][!hasMetaCols]), '!')
}
hasOneToOneRelationship <-
value[[2]] %in% cardinality(rawdata(object), group=value[[1]])
if (!all(hasOneToOneRelationship)) {
.error(funContext, 'The columns ',
.collapse(value[[2]][!hasOneToOneRelationship]),
' do not have a 1:1 relationship with the specified ID ',
'columns!')
}
}
# -- Function body
object@colDataMap <- value
return(object)
})
##
## -- colData
#' Convenience method to subset the `colData` out of the `rawdata` slot using
#' the assigned `colDataMap` metadata.
#'
#' @param x `LongTableDataMapper` object with valid data in the `rawdata` and
#' `colDataMap` slots.
#' @param key `logical(1)` Should the table be keyed according to the
#' `id_columns` of the `colDataMap` slot? This will sort the table in memory.
#' Default is TRUE.
#'
#' @return `data.table` The `colData` as specified in the `colDataMap` slot.
#'
#' @export
setMethod("colData", signature("LongTableDataMapper"), function(x, key=TRUE) {
.get_dimData(x, key, dim="col")
})
## ----------------
## ---- assayMap slot
#' @export
setGeneric('assayMap', function(object, ...) standardGeneric('assayMap'))
.docs_LongTableDataMapper_get_assayMap <- function(...) .parseToRoxygen(
"
@details
__assayMap__: A `list` of character vectors. The name of each list item
will be the assay in a `LongTableDataMapper` object that the columns in the
`character` vector will be assigned to. Column renaming occurs automatically
when the character vectors have names (from the value to the name).
@examples
assayMap({data_})
@md
@aliases assayMap,{class_},list-method assayMap,{class_},List-method
@exportMethod assayMap
",
...
)
#' @rdname LongTableDataMapper-accessors
#' @eval .docs_LongTableDataMapper_get_assayMap(class_=.local_class_3, data_=.local_data_3)
setMethod('assayMap', signature(object='LongTableDataMapper'),
function(object) {
object@assayMap
})
#' @export
setGeneric('assayMap<-', function(object, ..., value) standardGeneric('assayMap<-'))
#' @noRd
.docs_LongTableDataMapper_set_assayMap <- function(...) .parseToRoxygen(
"
@details
__assayMap<-__: Updates the `@assayMap` slot of a `{class_}` object,
returning an invisible NULL. Arguments:
- value: A `list` of character vectors, where the name of each list
item is the name of an assay and the values of each character vector
specify the columns mapping to the assay in the `S4` object the
`{class_}` constructs.
@examples
assayMap({data_}) <- list(sensitivity=c(viability1='viability'))
@md
@aliases assayMap<-,{class_},list-method assayMap<-,{class_},List-methhod
@exportMethod assayMap<-
",
...
)
#' @rdname LongTableDataMapper-accessors
#' @eval .docs_LongTableDataMapper_set_assayMap(class_=.local_class_3, data_=.local_data_3)
setReplaceMethod('assayMap', signature(object='LongTableDataMapper',
value='list_OR_List'), function(object, value) {
funContext <- '[CoreGx::`assayMap<-,LongTableDataMapper-method`]\n\t'
rawdataCols <- colnames(rawdata(object))
if (length(names(value)) == 0) stop(.errorMsg('The value argument must
be a named list-like of column name character vectors!'))
for (i in seq_along(value)) {
hasRawdataCols <- unlist(value[[i]]) %in% rawdataCols
if (!all(hasRawdataCols) && length(rawdata(object))) {
stop(.errorMsg(funContext, 'There are no columns named ',
.collapse(unlist(value[[i]])[!hasRawdataCols]),
' in the rawdata of this ', class(object)[1],
' object. Please ensure item ',
names(value)[i], ' of value has valid column names.'))
}
}
object@assayMap <- value
return(object)
})
#' Extract the data for an assay from a `LongTableDataMapper`
#'
#' @param x `LongTableDataMapper` The object to retrive assay data form according
#' to the `assayMap` slot.
#' @param i `character(1)` Name of an assay in the `assayMap` slot of `x`.
#' @param withDimnames `logical(1)` For compatibility with
#' `SummarizedExperiment::assay` generic. Not used.
#'
#' @return `data.table` Data for the specified assay extracted from the
#' `rawdata` slot of `x`.
#'
#' @importFrom checkmate assertSubset assertCharacter
#' @keywords internal
setMethod("assay", signature(x="LongTableDataMapper"),
function(x, i, withDimnames=TRUE) {
# Input validation
.assayMap <- assayMap(x)
assertCharacter(i, max.len=1)
assertSubset(i, names(.assayMap))
# Execution context
funContext <- paste0("\n[", getPackageName(), "::assay,", class(x)[1],
"-method]")
return(.get_dimDataFromMap(x, key=TRUE, .assayMap[[i]],
funContext=funContext))
})
#' Extract the data for all assays from a `LongTableDataMapper`
#'
#' @param x `LongTableDataMapper` The object to retrive assay data form according
#' to the `assayMap` slot.
#' @param withDimNames `logical(1)` For compatibility with
#' `SummarizedExperiment::assay` generic. Not used.
#'
#' @return `list` Data for all assays extracted from the
#' `rawdata` slot of `x` as a `list` of `data.tables`, where the `keys` for
#' each table are their `id_columns`.
#'
#' @importFrom checkmate assertSubset assertCharacter
#' @keywords internal
setMethod("assays", signature(x="LongTableDataMapper"),
function(x, withDimnames=TRUE) {
lapply(names(assayMap(x)), FUN=assay, x=x) |>
setNames(names(assayMap(x)))
})
# -- metadataMap
#' @export
setGeneric('metadataMap', function(object, ...) standardGeneric('metadataMap'))
#' @noRd
.docs_LongTableDataMapper_get_metadataMap <- function(...) .parseToRoxygen(
"
@details
__metadataMap__: A `list` of `character` vectors. Each item is an element
of the constructed objects `@metadata` slot.
@examples
metadataMap({data_})
@md
@aliases metadataMap,{class_}-method
@exportMethod metadataMap
",
...
)
#' @rdname LongTableDataMapper-accessors
#' @eval .docs_LongTableDataMapper_get_metadataMap(class_=.local_class_3, data_=.local_data_3)
setMethod('metadataMap', signature(object='LongTableDataMapper'),
function(object) {
object@metadataMap
})
#' @export
setGeneric('metadataMap<-', function(object, ..., value)
standardGeneric('metadataMap<-'))
#' @noRd
.docs_LongTableDataMapper_set_metadataMap <- function(...) .parseToRoxygen(
"
@details
__metadataMap<-__: Updates `{class_}` object in-place, then returns an
`invisible(NULL)`. Arguments:
- value: A `list` of `character` vectors. The name of each list item
is the name of the item in the `@metadata` slot of the `{class_}` object
created when `metaConstruct` is called on the `DataMapper`, and a
character vector specifies the columns of `@rawdata` to assign to each item.
@examples
metadataMap({data_}) <- list(object_metadata=c('metadata'))
@md
@aliases metadataMap<-,{class_}-method
@exportMethod metadataMap<-
",
...
)
#' @rdname LongTableDataMapper-accessors
#' @eval .docs_LongTableDataMapper_set_metadataMap(class_=.local_class_3, data_=.local_data_3, col_='metadata')
setReplaceMethod('metadataMap', signature(object='LongTableDataMapper',
value='list_OR_List'), function(object, value) {
funContext <- '[CoreGx::`metadataMap<-,LongTableDataMapper-method`]\n\t'
rawdataCols <- colnames(rawdata(object))
if (length(names(value)) == 0) stop(.errorMsg('The value argument must
be a named list-like of column name character vectors!'))
for (i in seq_along(value)) {
hasRawdataCols <- value[[i]] %in% rawdataCols
if (!all(hasRawdataCols) && length(rawdata(object))) {
stop(.errorMsg(funContext, 'There are no columns named ',
.collapse(value[[i]][!hasRawdataCols]), ' in the rawdata ',
'of this ', class(object)[1], ' object. Please ensure item ',
names(value)[i], ' of value has valid column names.'))
}
}
object@metadataMap <- value
return(object)
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.