Add loomR::combine
authorPaul Hoffman <phoffman@nygenome.org>
Thu, 1 Mar 2018 00:35:51 +0000 (19:35 -0500)
committerPaul Hoffman <phoffman@nygenome.org>
Thu, 1 Mar 2018 00:35:51 +0000 (19:35 -0500)
NAMESPACE
R/loom.R
man/combine.Rd [new file with mode: 0644]

index 8b91e8f47a77fe18e5a920c7173e9890b4b82bc0..1224254e8e4c5408b494a46ae8756208034eeeac 100644 (file)
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -1,5 +1,6 @@
 # Generated by roxygen2: do not edit by hand
 
+export(combine)
 export(connect)
 export(create)
 export(loom)
index 7a6882a7d77dc4ccf167673da04b33bc72dc01f1..4f23876396e4484bf8aea342768b8c53287b165e 100644 (file)
--- a/R/loom.R
+++ b/R/loom.R
@@ -1264,7 +1264,7 @@ subset.loom <- function(
 
 #' Combine loom files
 #'
-#' @param x A vector of loom files or filenames
+#' @param looms A vector of loom files or filenames
 #' @param filename Name for resultant vector
 #' @param chunk.size How many rows form each input loom should we stream to the merged loom file at any given time?
 #' @param order.by Optional row attribute to order each input loom by, must be one dimensional
@@ -1275,6 +1275,8 @@ subset.loom <- function(
 #'
 #' @importFrom utils setTxtProgressBar
 #'
+#' @seealso \code{\link{loom-class}}
+#'
 #' @export
 #'
 combine <- function(
@@ -1515,13 +1517,12 @@ combine <- function(
     }
   }
   # Start adding loom objects
+  matrix.previous <- 0
   col.previous <- vector(mode = 'integer', length = length(x = col.attrs))
   names(x = col.previous) <- unlist(x = col.attrs)
-  lay.previous <- vector(mode = 'integer', length = length(x = layers))
-  names(x = lay.previous) <- unlist(x = layers)
   for (i in 1:length(x = looms)) {
     if (display.progress) {
-      catn("Adding loom file", i ,"of", length(x = looms))
+      catn("\nAdding loom file", i ,"of", length(x = looms))
     }
     # Open the loom file
     this <- if (is.character(x = looms[i])) {
@@ -1548,38 +1549,68 @@ combine <- function(
       cells.use <- chunk.points[1, col]:chunk.points[2, col]
       # Add /matrix for this chunk
       matrix.add <- this[['matrix']][cells.use, ]
-      new.loom[['matrix']][cells.use, ] <- matrix.add[, order.genes]
+      new.loom[['matrix']][cells.use + matrix.previous, ] <- matrix.add[, order.genes]
       # Add layers for this chunk
       for (lay in list.datasets(object = this[['layers']])) {
         lay.add <- this[['layers']][[lay]][cells.use, ]
-        new.loom[['layers']][[lay]][cells.use, ] <- lay.add[, order.genes]
+        new.loom[['layers']][[lay]][cells.use + matrix.previous, ] <- lay.add[, order.genes]
       }
       if (display.progress) {
         setTxtProgressBar(pb = pb, value = col / ncol(x = chunk.points))
       }
       gc()
     }
+    matrix.previous <- matrix.previous + max(chunk.points)
     # Add col_attrs for this chunk
+    if (display.progress) {
+      catn("\nAdding data to /col_attrs")
+      pb <- new.pb()
+    }
     for (attr in list.datasets(object = this[['col_attrs']], full.names = TRUE)) {
       start <- col.previous[attr]
-      end <- start + this[[attr]]$dims
+      end <- start + this[[attr]]$dims[length(x = this[[attr]]$dims)]
       if (col.ndims[[attr]] == 1) {
-        new.loom[[attr]][start:end] <- this[[attr]][]
+        new.loom[[attr]][(start + 1):end] <- this[[attr]][]
       } else {
         for (col in 1:ncol(x = chunk.points)) {
-
+          col.use <- chunk.points[1, col]:chunk.points[2, col]
+          new.loom[[attr]][col.use, (start + 1):end] <- this[[attr]][col.use, ]
         }
       }
-      col.previous[attr] <- end + 1
+      col.previous[attr] <- end
+      if (display.progress) {
+        setTxtProgressBar(
+          pb = pb,
+          value = grep(
+            pattern = attr,
+            x = list.datasets(object = this[['col_attrs']], full.names = TRUE)
+          ) / length(x = list.datasets(object = this[['col_attrs']], full.names = TRUE))
+        )
+      }
     }
     # Copy row attributes from the first loom object into the merged one
     if (i == 1) {
-      catn()
+      if (display.progress) {
+        catn("\nCopying data for /row_attrs")
+        pb <- new.pb()
+      }
+      for (attr in list.datasets(object = this, path = 'row_attrs')) {
+        new.loom[['row_attrs']]$obj_copy_from(
+          src_loc = this[['row_attrs']],
+          src_name = attr,
+          dst_name = attr
+        )
+        if (display.progress) {
+          setTxtProgressBar(
+            pb = pb,
+            value = grep(
+              pattern = attr,
+              x = list.datasets(object = this[['row_attrs']])
+            ) / length(x = list.datasets(object = this[['row_attrs']]))
+          )
+        }
+      }
     }
-    # Add data to /layers
-    # Add data to /col_attrs
-    # Add data to /row_attrs, using values from the first loom object only
-    catn()
     new.loom$flush()
     # Close current loom file, if not open previously
     if (is.character(x = looms[i])) {
diff --git a/man/combine.Rd b/man/combine.Rd
new file mode 100644 (file)
index 0000000..21ed97b
--- /dev/null
@@ -0,0 +1,31 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/loom.R
+\name{combine}
+\alias{combine}
+\title{Combine loom files}
+\usage{
+combine(looms, filename, chunk.size = 1000, order.by = NULL,
+  overwrite = FALSE, display.progress = TRUE, ...)
+}
+\arguments{
+\item{looms}{A vector of loom files or filenames}
+
+\item{filename}{Name for resultant vector}
+
+\item{chunk.size}{How many rows form each input loom should we stream to the merged loom file at any given time?}
+
+\item{order.by}{Optional row attribute to order each input loom by, must be one dimensional}
+
+\item{overwrite}{Overwrite \code{filename} if already exists?}
+
+\item{display.progress}{Display progress as we're copying over data}
+}
+\value{
+A loom object connected to \code{filename}
+}
+\description{
+Combine loom files
+}
+\seealso{
+\code{\link{loom-class}}
+}