From 8410a63ff3b1dc38c35b21873c4594b5b88d8029 Mon Sep 17 00:00:00 2001 From: Andrew McDavid Date: Fri, 25 Apr 2014 13:56:58 -0700 Subject: [PATCH] Add coercion method from ExpressionSets; DataLayer docs --- DESCRIPTION | 2 +- R/AllClasses.R | 40 ++++++++++++++++++++++++++++++++- R/DataLayer.R | 4 ++++ R/Fluidigm-methods.R | 2 +- R/SingleCellAssay-methods.R | 22 ++++++++++++++++++- inst/tests/test-DataLayer.R | 8 +++---- man/DataLayer-class.Rd | 44 +++++++++++++++++++++++++++++++++++++ 7 files changed, 114 insertions(+), 8 deletions(-) create mode 100644 man/DataLayer-class.Rd diff --git a/DESCRIPTION b/DESCRIPTION index 5f9683b..1e5dde1 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: SingleCellAssay Type: Package Title: Core data structures for single-cell assays -Version: 0.79 +Version: 0.80 Date: 2014-04-08 Author: Andrew McDavid , Greg Finak Maintainer: Greg Finak diff --git a/R/AllClasses.R b/R/AllClasses.R index 8450daa..bcb94da 100644 --- a/R/AllClasses.R +++ b/R/AllClasses.R @@ -5,8 +5,46 @@ NULL -#setOldClass("ncdf") +##' DataLayer class +##' +##' DataLayer is a 3-D array, wrapped to make it look like a matrix. +##' It is used to hold matrix-like expression data, for which we might want to keep several representations (transformations) around. +##' The number of matrix "layers" is given by the trailing dimension. +##' Dimensions 1 and 2 correspond to the "rows" and "columns" of the matrix. +##' The layer that is active can be set, and additional layers created (concatenated). +##' } +##' \section{Slots}{ +##' DataLayer extends array, and has the following additional slots +##' \describe{ +##' \item{.Data}{the underlying array} +##' \item{valid}{a \code{logical} that may optionally indicate the freshness of derived layers (if the underlying data changes). Not currently used.} +##' \item{layer}{which 'slice' of the array is being used} +##' }} +##' \section{Methods}{ +##' \describe{ +##' \item{addlayer}{Concatentate another slice onto the object} +##' \item{layername}{Return the name of the current slice} +##' \item{layer}{Return the active layer} +##' \item{layer<-}{Set the active layer} +##' \item{exprs}{Return the matrix representation of the active layer} +##' \item{exprs<-}{Replace the matrix on the current layer.} +##' } +##' @examples +##' ar <- array(1:10, dim=c(2, 5, 1)) +##' dl <- new('DataLayer', .Data=ar) +##' nrow(dl) #2 +##' ncol(dl) #5 +##' layer(dl) +##' dl <- addlayer(dl, 'negative') +##' ex <- exprs(dl) +##' layer(dl) <- 'negative' #or could use 2 +##' exprs(dl)<- -ex +##' exprs(dl) +##' @name DataLayer-class +##' @docType class +##' @aliases DataLayer +##' @seealso \code{\link{SingleCellAssay}}, \code{\link{SingleCellAssay-class}} setClass('DataLayer', contains='array', representation=representation(layer='numeric', valid='logical'), prototype=prototype(array(NA, dim=c(0, 0, 1)), layer=1L, valid=TRUE), validity=function(object){ #cat('DL dim ', dim(object@.Data), '\n') length(dim(object@.Data))==3 diff --git a/R/DataLayer.R b/R/DataLayer.R index 1235175..f7e45f2 100644 --- a/R/DataLayer.R +++ b/R/DataLayer.R @@ -115,7 +115,11 @@ setMethod("exprs",signature(object="DataLayer"),function(object){ setMethod('initialize', 'DataLayer', function(.Object, ...){ ## message('init DataLayer') #DEBUG + ## This is (was?) necessary initialize since we inherit from 'array' + ## But is rather mysterious, nonetheless. .Object <- getMethod('initialize', 'ANY')(.Object, ...) + dn <- dimnames(.Object@.Data) + dimnames(.Object@.Data) <-if(is.null(dn)) list(wells=NULL, features=NULL, layers=NULL) else dn .Object }) diff --git a/R/Fluidigm-methods.R b/R/Fluidigm-methods.R index e53cf17..26b8d50 100644 --- a/R/Fluidigm-methods.R +++ b/R/Fluidigm-methods.R @@ -237,7 +237,7 @@ filter <- function(sc, groups=NULL, filt_control=NULL, apply_filter=TRUE){ if (!is.null(groups)) { checkGroups(sc, groups) scL <- split(sc, groups) - lapp <- lapply(scL, filter, groups=NULL, filt_control, apply_filter) + lapp <- lapply(scL, filter, groups=NULL, filt_control=filt_control, apply_filter=apply_filter) ## Do various things with lapp: if(apply_filter && filt_control$filter){ ## list of SingleCellAssays diff --git a/R/SingleCellAssay-methods.R b/R/SingleCellAssay-methods.R index 061a314..0ba9bc7 100644 --- a/R/SingleCellAssay-methods.R +++ b/R/SingleCellAssay-methods.R @@ -204,7 +204,7 @@ fixdf <- function(df, idvars, primerid, measurement, cmap, fmap, keep.names){ ## unnamed arguments get passed along to callNextMethod ## which eventually just sets the slots setMethod('initialize', 'SingleCellAssay', - function(.Object, dataframe, idvars, primerid, measurement, cellvars=NULL, featurevars=NULL, phenovars=NULL, sort=TRUE, ...){ + function(.Object, dataframe, idvars, primerid, measurement, exprsMatrix, cellvars=NULL, featurevars=NULL, phenovars=NULL, sort=TRUE, ...){ ##message(class(.Object), ' calling SingleCellAssay Initialize') #DEBUG .Object <- callNextMethod() if(sort) .Object <- sort(.Object) @@ -639,3 +639,23 @@ setMethod('combine', signature=c(x='SingleCellAssay', y='AnnotatedDataFrame'), f slot(x, along) <- newdata x }) + +setAs('ExpressionSet', 'SingleCellAssay', function(from){ + ## just a transposed version + ex <- t(exprs(from)) + dn <- dimnames(ex) + names(dn) <- c('wellKey', 'primerid') + dim(ex) <- c(dim(ex), 1) + pd <- phenoData(from) + pData(pd)[,'wellKey'] <- sampleNames(pd) + fd <- featureData(from) + fd$primerid <- sampleNames(fd) + dimnames(ex) <- c(dn, layer='ExpressionSet') + DL <- new('DataLayer', .Data=ex) + new('SingleCellAssay', .Data=DL, featureData=fd, cellData=pd, sort=FALSE) +}) + +## setAs('SingleCellAssay', 'data.table', function(from){ +## dt <- data.table(as.vector(exprs(from))) + +## }) diff --git a/inst/tests/test-DataLayer.R b/inst/tests/test-DataLayer.R index 4c68203..7999695 100644 --- a/inst/tests/test-DataLayer.R +++ b/inst/tests/test-DataLayer.R @@ -36,19 +36,19 @@ test_that('doubleton dl works', { context('subset and replace') test_that('subset works', { - expect_equal(dl[[,1]], mat[,1,drop=FALSE]) - expect_equal(dl[[1,]], mat[1,,drop=FALSE]) + expect_equal(dl[[,1]], mat[,1,drop=FALSE], check.names=FALSE) + expect_equal(dl[[1,]], mat[1,,drop=FALSE], check.names=FALSE) matidx <- cbind(c(1, 1, 2), 1:3) expect_equal(dl[[matidx]], mat[matidx]) mat[matidx] <- -999 dl[[matidx]] <- -999 - expect_equal(exprs(dl), mat) + expect_equal(exprs(dl), mat, check.attributes=FALSE) }) test_that('[ subscripting works', { expect_is(dl[1,], 'DataLayer') expect_is(dl[,2:3], 'DataLayer') - expect_equal(exprs(dl[1,]), dl[[1,,drop=FALSE]]) + expect_equal(exprs(dl[1,]), dl[[1,,drop=FALSE]], check.attributes=FALSE) }) spl <- split(dl, 1:2) diff --git a/man/DataLayer-class.Rd b/man/DataLayer-class.Rd new file mode 100644 index 0000000..b2657d7 --- /dev/null +++ b/man/DataLayer-class.Rd @@ -0,0 +1,44 @@ +\docType{class} +\name{DataLayer-class} +\alias{DataLayer} +\alias{DataLayer-class} +\title{DataLayer class} +\description{ +DataLayer is a 3-D array, wrapped to make it look like a +matrix. It is used to hold matrix-like expression data, for +which we might want to keep several representations +(transformations) around. The number of matrix "layers" is +given by the trailing dimension. Dimensions 1 and 2 +correspond to the "rows" and "columns" of the matrix. The +layer that is active can be set, and additional layers +created (concatenated). } \section{Slots}{ DataLayer +extends array, and has the following additional slots +\describe{ \item{.Data}{the underlying array} +\item{valid}{a \code{logical} that may optionally indicate +the freshness of derived layers (if the underlying data +changes). Not currently used.} \item{layer}{which 'slice' +of the array is being used} }} \section{Methods}{ +\describe{ \item{addlayer}{Concatentate another slice onto +the object} \item{layername}{Return the name of the current +slice} \item{layer}{Return the active layer} +\item{layer<-}{Set the active layer} \item{exprs}{Return +the matrix representation of the active layer} +\item{exprs<-}{Replace the matrix on the current layer.} } +} +\examples{ +ar <- array(1:10, dim=c(2, 5, 1)) +dl <- new('DataLayer', .Data=ar) +nrow(dl) #2 +ncol(dl) #5 +layer(dl) +dl <- addlayer(dl, 'negative') +ex <- exprs(dl) +layer(dl) <- 'negative' #or could use 2 +exprs(dl)<- -ex +exprs(dl) +} +\seealso{ +\code{\link{SingleCellAssay}}, +\code{\link{SingleCellAssay-class}} +} +