├── DESCRIPTION ├── NAMESPACE ├── NEWS ├── R ├── AtomicList-class.R ├── AtomicList-utils.R ├── CompressedAtomicList-class.R ├── CompressedDataFrameList-class.R ├── CompressedGrouping-class.R ├── CompressedHitsList-class.R ├── CompressedList-class.R ├── CompressedList-comparison.R ├── CompressedRangesList-class.R ├── DataFrameList-class.R ├── DataFrameList-utils.R ├── Grouping-class.R ├── Hits-class-leftovers.R ├── IPos-class.R ├── IPosList-class.R ├── IPosRanges-class.R ├── IPosRanges-comparison.R ├── IRanges-class.R ├── IRanges-constructor.R ├── IRanges-utils.R ├── IRangesList-class.R ├── IntegerRangesList-class.R ├── MaskCollection-class.R ├── NCList-class.R ├── RangedSelection-class.R ├── Ranges-and-RangesList-classes.R ├── Rle-class-leftovers.R ├── RleViews-class.R ├── RleViews-utils.R ├── RleViewsList-class.R ├── RleViewsList-utils.R ├── SimpleGrouping-class.R ├── Vector-class-leftovers.R ├── Views-class.R ├── ViewsList-class.R ├── cbind-Rle-methods.R ├── coverage-methods.R ├── cvg-methods.R ├── extractList.R ├── extractListFragments.R ├── findOverlaps-methods.R ├── inter-range-methods.R ├── intra-range-methods.R ├── multisplit.R ├── nearest-methods.R ├── range-squeezers.R ├── read.Mask.R ├── reverse-methods.R ├── seqapply.R ├── setops-methods.R ├── slice-methods.R ├── subsetting-utils.R ├── tile-methods.R ├── windows-methods.R └── zzz.R ├── README.md ├── TODO ├── inst ├── CITATION ├── extdata │ ├── ce2chrM.bed │ ├── ce2chrM.fa.out │ ├── hg18liftAll.lft │ └── hs_b36v3_chrY.agp ├── include │ ├── IRanges_defines.h │ ├── IRanges_interface.h │ └── _IRanges_stubs.c └── unitTests │ ├── test_AtomicList-class.R │ ├── test_AtomicList-utils.R │ ├── test_DataFrame-utils.R │ ├── test_DataFrameList.R │ ├── test_Grouping-class.R │ ├── test_HitsList.R │ ├── test_IPos-class.R │ ├── test_IRanges-class.R │ ├── test_IRanges-constructor.R │ ├── test_IRangesList-class.R │ ├── test_NCList-class.R │ ├── test_Ranges-comparison.R │ ├── test_RleViews.R │ ├── test_RleViewsList.R │ ├── test_coverage-methods.R │ ├── test_extractList.R │ ├── test_findOverlaps-methods.R │ ├── test_inter-range-methods.R │ ├── test_intra-range-methods.R │ ├── test_nearest-methods.R │ ├── test_seqapply.R │ ├── test_setops-methods.R │ ├── test_split.R │ ├── test_splitListElements.R │ └── test_tile-methods.R ├── man ├── AtomicList-class.Rd ├── AtomicList-utils.Rd ├── CompressedHitsList-class.Rd ├── CompressedList-class.Rd ├── DataFrameList-class.Rd ├── Grouping-class.Rd ├── Hits-class-leftovers.Rd ├── IPos-class.Rd ├── IPosRanges-class.Rd ├── IPosRanges-comparison.Rd ├── IRanges-class.Rd ├── IRanges-constructor.Rd ├── IRanges-internals.Rd ├── IRanges-utils.Rd ├── IRangesList-class.Rd ├── IntegerRanges-class.Rd ├── IntegerRangesList-class.Rd ├── MaskCollection-class.Rd ├── NCList-class.Rd ├── RangedSelection-class.Rd ├── Rle-class-leftovers.Rd ├── RleViews-class.Rd ├── RleViewsList-class.Rd ├── Vector-class-leftovers.Rd ├── Views-class.Rd ├── ViewsList-class.Rd ├── coverage-methods.Rd ├── extractList.Rd ├── extractListFragments.Rd ├── findOverlaps-methods.Rd ├── inter-range-methods.Rd ├── intra-range-methods.Rd ├── multisplit.Rd ├── nearest-methods.Rd ├── range-squeezers.Rd ├── read.Mask.Rd ├── reverse-methods.Rd ├── seqapply.Rd ├── setops-methods.Rd ├── slice-methods.Rd └── view-summarization-methods.Rd ├── src ├── CompressedAtomicList_utils.c ├── CompressedIRangesList_class.c ├── CompressedList_class.c ├── Grouping_class.c ├── IPosRanges_comparison.c ├── IRanges.h ├── IRanges_class.c ├── IRanges_constructor.c ├── NCList.c ├── R_init_IRanges.c ├── Ranges_class.c ├── RleViews_utils.c ├── S4Vectors_stubs.c ├── SimpleIRangesList_class.c ├── coverage_methods.c ├── extractListFragments.c └── inter_range_methods.c ├── tests └── run_unitTests.R └── vignettes └── IRangesOverview.Rnw /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: IRanges 2 | Title: Foundation of integer range manipulation in Bioconductor 3 | Description: Provides efficient low-level and highly reusable S4 4 | classes for storing, manipulating and aggregating over annotated 5 | ranges of integers. Implements an algebra of range operations, 6 | including efficient algorithms for finding overlaps and nearest 7 | neighbors. Defines efficient list-like classes for storing, 8 | transforming and aggregating large grouped data, i.e., collections 9 | of atomic vectors and DataFrames. 10 | biocViews: Infrastructure, DataRepresentation 11 | URL: https://bioconductor.org/packages/IRanges 12 | BugReports: https://github.com/Bioconductor/IRanges/issues 13 | Version: 2.43.0 14 | License: Artistic-2.0 15 | Encoding: UTF-8 16 | Authors@R: c( 17 | person("Hervé", "Pagès", role=c("aut", "cre"), 18 | email="hpages.on.github@gmail.com"), 19 | person("Patrick", "Aboyoun", role="aut"), 20 | person("Michael", "Lawrence", role="aut")) 21 | Depends: R (>= 4.0.0), methods, utils, stats, 22 | BiocGenerics (>= 0.53.2), S4Vectors (>= 0.45.4) 23 | Imports: stats4 24 | LinkingTo: S4Vectors 25 | Suggests: XVector, GenomicRanges, Rsamtools, GenomicAlignments, GenomicFeatures, 26 | BSgenome.Celegans.UCSC.ce2, pasillaBamSubset, RUnit, BiocStyle 27 | Collate: range-squeezers.R 28 | Vector-class-leftovers.R 29 | DataFrameList-class.R 30 | DataFrameList-utils.R 31 | AtomicList-class.R 32 | AtomicList-utils.R 33 | Ranges-and-RangesList-classes.R 34 | IPosRanges-class.R 35 | IPosRanges-comparison.R 36 | IntegerRangesList-class.R 37 | IRanges-class.R 38 | IRanges-constructor.R 39 | IRanges-utils.R 40 | Rle-class-leftovers.R 41 | IPos-class.R 42 | subsetting-utils.R 43 | Grouping-class.R 44 | Views-class.R 45 | RleViews-class.R 46 | RleViews-utils.R 47 | extractList.R 48 | seqapply.R 49 | multisplit.R 50 | SimpleGrouping-class.R 51 | IRangesList-class.R 52 | IPosList-class.R 53 | ViewsList-class.R 54 | RleViewsList-class.R 55 | RleViewsList-utils.R 56 | RangedSelection-class.R 57 | MaskCollection-class.R 58 | read.Mask.R 59 | CompressedList-class.R 60 | CompressedList-comparison.R 61 | CompressedHitsList-class.R 62 | CompressedDataFrameList-class.R 63 | CompressedAtomicList-class.R 64 | CompressedGrouping-class.R 65 | CompressedRangesList-class.R 66 | Hits-class-leftovers.R 67 | NCList-class.R 68 | findOverlaps-methods.R 69 | windows-methods.R 70 | intra-range-methods.R 71 | inter-range-methods.R 72 | reverse-methods.R 73 | coverage-methods.R 74 | cvg-methods.R 75 | slice-methods.R 76 | setops-methods.R 77 | nearest-methods.R 78 | cbind-Rle-methods.R 79 | tile-methods.R 80 | extractListFragments.R 81 | zzz.R 82 | -------------------------------------------------------------------------------- /R/CompressedDataFrameList-class.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### CompressedDataFrameList objects 3 | ### ------------------------------------------------------------------------- 4 | 5 | 6 | setClass("CompressedDataFrameList", 7 | contains=c("DataFrameList", "CompressedList"), 8 | representation("VIRTUAL", unlistData="DataFrame"), 9 | prototype(unlistData=new("DFrame")) 10 | ) 11 | 12 | setClass("CompressedDFrameList", 13 | contains=c("DFrameList", "CompressedDataFrameList"), 14 | representation(unlistData="DFrame") 15 | ) 16 | 17 | setClass("CompressedSplitDataFrameList", 18 | contains=c("SplitDataFrameList", "CompressedDataFrameList"), 19 | representation("VIRTUAL") 20 | ) 21 | 22 | setClass("CompressedSplitDFrameList", 23 | contains=c("SplitDFrameList", "CompressedDFrameList", 24 | "CompressedSplitDataFrameList") 25 | ) 26 | 27 | 28 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 29 | ### Accessor methods. 30 | ### 31 | 32 | ### Deprecated. 33 | ### IMPORTANT NOTE: We won't be able to go thru the Defunct cycle because 34 | ### a lot of code around assumes that ncol() can be called on an arbitrary 35 | ### object! 36 | setMethod("ncol", "CompressedSplitDataFrameList", 37 | function(x) 38 | { 39 | msg <- c("The ncol() method for CompressedSplitDataFrameList ", 40 | "objects is deprecated. Please use ncols() on these ", 41 | "objects instead.") 42 | .Deprecated(msg=wmsg(msg)) 43 | if (length(x) == 0L) 44 | 0L 45 | else 46 | structure(rep.int(ncol(x@unlistData), length(x)), 47 | names = names(x)) 48 | }) 49 | 50 | setMethod("ncols", "CompressedSplitDataFrameList", 51 | function(x, use.names=TRUE) 52 | { 53 | if (!isTRUEorFALSE(use.names)) 54 | stop(wmsg("'use.names' must be TRUE or FALSE")) 55 | ans_names <- if (use.names) names(x) else NULL 56 | structure(rep.int(ncol(x@unlistData), length(x)), names=ans_names) 57 | } 58 | ) 59 | 60 | setMethod("colnames", "CompressedSplitDataFrameList", 61 | function(x, do.NULL = TRUE, prefix = "col") 62 | { 63 | if (length(x)) { 64 | nms <- colnames(x@unlistData, do.NULL = do.NULL, prefix = prefix) 65 | rep(CharacterList(nms), length(x)) 66 | } else NULL 67 | }) 68 | 69 | setReplaceMethod("rownames", "CompressedSplitDataFrameList", 70 | function(x, value) 71 | { 72 | if (is.null(value)) { 73 | rownames(x@unlistData) <- NULL 74 | } else if (is(value, "CharacterList")){ 75 | if (length(x) != length(value)) 76 | stop("replacement value must be the same length as x") 77 | rownames(x@unlistData) <- unlist(value, use.names=FALSE) 78 | } else { 79 | stop("replacement value must either be NULL or a CharacterList") 80 | } 81 | x 82 | }) 83 | 84 | setReplaceMethod("colnames", "CompressedSplitDataFrameList", 85 | function(x, value) 86 | { 87 | if (is.null(value)) { 88 | colnames(x@unlistData) <- NULL 89 | } else if (is.character(value)) { 90 | colnames(x@unlistData) <- value 91 | } else if (is(value, "CharacterList")){ 92 | if (length(x) != length(value)) 93 | stop("replacement value must be the same length as x") 94 | if (length(x) > 0) 95 | colnames(x@unlistData) <- unlist(value[[1L]]) 96 | } else { 97 | stop("replacement value must either be NULL or a CharacterList") 98 | } 99 | x 100 | }) 101 | 102 | setMethod("commonColnames", "CompressedSplitDataFrameList", 103 | function(x) colnames(unlist(x, use.names=FALSE))) 104 | 105 | setMethod("columnMetadata", "CompressedSplitDataFrameList", function(x) { 106 | mcols(x@unlistData, use.names=FALSE) 107 | }) 108 | 109 | setReplaceMethod("columnMetadata", "CompressedSplitDataFrameList", 110 | function(x, value) { 111 | mcols(x@unlistData) <- value 112 | x 113 | }) 114 | 115 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 116 | ### Subsetting. 117 | ### 118 | 119 | setMethod("[", "CompressedSplitDataFrameList", 120 | function(x, i, j, ..., drop=TRUE) 121 | { 122 | if (!missing(j)) 123 | x@unlistData <- x@unlistData[, j, drop=FALSE] 124 | if (!missing(i)) 125 | x <- callNextMethod(x, i) 126 | 127 | if (((nargs() - !missing(drop)) > 2) && 128 | (ncol(x@unlistData) == 1) && (missing(drop) || drop)) { 129 | x <- relist(x@unlistData[[1L]], x) 130 | } 131 | 132 | x 133 | }) 134 | 135 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 136 | ### Coercion 137 | ### 138 | 139 | setAs("ANY", "CompressedDataFrameList", 140 | function(from) as(from, "CompressedDFrameList") 141 | ) 142 | setAs("ANY", "CompressedSplitDataFrameList", 143 | function(from) as(from, "CompressedSplitDFrameList") 144 | ) 145 | 146 | setListCoercions("DFrame") 147 | 148 | setAs("ANY", "CompressedSplitDFrameList", 149 | function(from) { 150 | coerceToCompressedList(from, "DFrame") 151 | }) 152 | 153 | setAs("ANY", "SplitDFrameList", 154 | function(from) as(from, "CompressedSplitDFrameList")) 155 | 156 | setAs("DataFrame", "SplitDFrameList", 157 | function(from) as(from, "CompressedSplitDFrameList")) 158 | 159 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 160 | ### Display 161 | ### 162 | 163 | setMethod("classNameForDisplay", "CompressedDFrameList", 164 | function(x) sub("^Compressed", "", sub("DFrame", "DataFrame", class(x))) 165 | ) 166 | 167 | -------------------------------------------------------------------------------- /R/CompressedGrouping-class.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### CompressedGrouping objects 3 | ### ------------------------------------------------------------------------- 4 | 5 | setClass("CompressedGrouping", 6 | ### TODO: contain VIRTUAL after R 3.4 release 7 | contains=c("Grouping", "CompressedIntegerList")) 8 | 9 | setClass("CompressedManyToOneGrouping", 10 | contains=c("ManyToOneGrouping", "CompressedGrouping")) 11 | 12 | setClass("CompressedManyToManyGrouping", 13 | contains=c("BaseManyToManyGrouping", "CompressedGrouping")) 14 | 15 | ### ------------------------------------------------------------------------- 16 | ### Grouping API implementation 17 | ### ---------------------------- 18 | ### 19 | 20 | setMethod("grouplengths", "CompressedGrouping", 21 | function(x, i=NULL) grouplengths(PartitioningByEnd(x), i)) 22 | 23 | setMethod("nobj", "CompressedManyToOneGrouping", 24 | function(x) nobj(PartitioningByEnd(x))) 25 | 26 | -------------------------------------------------------------------------------- /R/CompressedHitsList-class.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### CompressedHitsList objects 3 | ### ------------------------------------------------------------------------- 4 | 5 | ### [H.P. - 2015/12/17] Why do we need this? Where is it used? 6 | ### It's not even exported. 7 | 8 | setClass("CompressedHitsList", 9 | prototype = prototype(elementType = "Hits", 10 | unlistData = new("Hits")), 11 | contains="CompressedList") 12 | 13 | 14 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 15 | ### Accessors 16 | ### 17 | 18 | setMethod("from", "CompressedHitsList", function(x) from(x@unlistData)) 19 | setMethod("to", "CompressedHitsList", function(x) to(x@unlistData)) 20 | 21 | setMethod("nLnode", "CompressedHitsList", function(x) nLnode(x@unlistData)) 22 | setMethod("nRnode", "CompressedHitsList", function(x) nRnode(x@unlistData)) 23 | 24 | 25 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 26 | ### Constructor 27 | ### 28 | 29 | CompressedHitsList <- function(hits, query) 30 | { 31 | if (!(is(query, "CompressedIRangesList"))) 32 | stop("'query' must be a 'CompressedIRangesList' object") 33 | if (!is(hits, "Hits")) 34 | stop("'hits' must be a 'Hits' object") 35 | 36 | qspace <- space(query) 37 | hspace <- as.integer(qspace[queryHits(hits)]) 38 | partitioning <- PartitioningByEnd(hspace, names=names(query@partitioning), NG=length(names(query@partitioning))) 39 | newCompressedList0("CompressedHitsList", unlistData=hits, partitioning=partitioning) 40 | } 41 | 42 | 43 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 44 | ### Coercion 45 | ### 46 | 47 | ## return as.matrix as on Hits, with indices adjusted 48 | 49 | setMethod("as.matrix", "CompressedHitsList", function(x) { 50 | cbind(queryHits=queryHits(x), subjectHits=subjectHits(x)) 51 | }) 52 | 53 | -------------------------------------------------------------------------------- /R/CompressedList-comparison.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### Comparing and ordering CompressedList objects 3 | ### ------------------------------------------------------------------------- 4 | ### 5 | ### Overwrite methods defined in S4Vectors/R/List-comparison.R for List 6 | ### objects with optimized methods for CompressedList objects. 7 | ### 8 | 9 | 10 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 11 | ### Element-wise (aka "parallel") comparison of 2 List objects. 12 | ### 13 | ### TODO: Add optimized "==" and "<=" methods for CompressedList objects. 14 | ### 15 | 16 | setMethod("!", "CompressedList", 17 | function(x) relist(!unlist(x, use.names=FALSE), x) 18 | ) 19 | 20 | 21 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 22 | ### match() 23 | ### 24 | 25 | ### The first match method catches CompressedList,list; 'table' is atomic 26 | setMethod("match", c("CompressedList", "vector"), 27 | function(x, table, nomatch = NA_integer_, incomparables = NULL, ...) 28 | { 29 | m <- match(x@unlistData, table, nomatch=nomatch, 30 | incomparables=incomparables, ...) 31 | relist(m, x) 32 | }) 33 | 34 | 35 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 36 | ### duplicated() & unique() 37 | ### 38 | 39 | .duplicated.CompressedList <- function(x, incomparables=FALSE, 40 | fromLast=FALSE, nmax=NA) 41 | { 42 | if (!identical(incomparables, FALSE)) 43 | stop("\"duplicated\" method for CompressedList objects ", 44 | "does not support the 'incomparables' argument") 45 | x_unlistData <- x@unlistData 46 | sm <- match(x_unlistData, x_unlistData) # doesn't work on an Rle 47 | x_group <- rep.int(seq_along(x), elementNROWS(x)) 48 | ans_unlistData <- duplicatedIntegerPairs(x_group, sm, fromLast=fromLast) 49 | relist(ans_unlistData, x) 50 | } 51 | setMethod("duplicated", "CompressedList", .duplicated.CompressedList) 52 | 53 | .unique.CompressedList <- function(x, ...) 54 | { 55 | is_dup <- duplicated(x, ...) 56 | x_unlistData <- x@unlistData 57 | keep_idx <- which(!is_dup@unlistData) 58 | ans_unlistData <- x_unlistData[keep_idx] 59 | x_group <- rep.int(seq_along(x), elementNROWS(x)) 60 | ans_group <- x_group[keep_idx] 61 | ans_partitioning <- PartitioningByEnd(ans_group, NG=length(x), 62 | names=names(x)) 63 | relist(ans_unlistData, ans_partitioning) 64 | } 65 | setMethod("unique", "CompressedList", .unique.CompressedList) 66 | 67 | 68 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 69 | ### %in% 70 | ### 71 | 72 | ### The "%in%" method for Vector objects calls is.na() internally. 73 | setMethod("is.na", "CompressedList", 74 | function(x) relist(is.na(unlist(x, use.names=FALSE)), x) 75 | ) 76 | 77 | 78 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 79 | ### order() and related methods. 80 | ### 81 | ### TODO: Add optimized methods for CompressedList objects. 82 | ### 83 | 84 | -------------------------------------------------------------------------------- /R/DataFrameList-utils.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### DataFrameList utilities 3 | ### ------------------------------------------------------------------------- 4 | 5 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 6 | ### Combining. 7 | ### 8 | 9 | setMethod("cbind", "DataFrameList", 10 | function(..., deparse.level=1) mendoapply(cbind, ...)) 11 | 12 | setMethod("rbind", "DataFrameList", 13 | function(..., deparse.level=1) mendoapply(rbind, ...)) 14 | 15 | setMethod("stack", "DataFrameList", 16 | function(x, index.var = "name") 17 | { 18 | DataFrame(S4Vectors:::stack_index(x, index.var), 19 | unlist(x, use.names=FALSE), 20 | row.names = unlist(lapply(x, rownames))) 21 | }) 22 | 23 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 24 | ### Transforming. 25 | ### 26 | 27 | setClass("SDFLWrapperForTransform", 28 | representation(delegate = "SplitDataFrameList"), 29 | contains="Vector") 30 | 31 | setMethod("colnames", "SDFLWrapperForTransform", function(x) { 32 | commonColnames(x@delegate) 33 | }) 34 | 35 | setMethod("[[", "SDFLWrapperForTransform", function (x, i, j, ...) { 36 | x@delegate[,i] 37 | }) 38 | 39 | setReplaceMethod("[[", "SDFLWrapperForTransform", function(x, i, j, ..., value) { 40 | x@delegate[,i] <- value 41 | x 42 | }) 43 | 44 | setMethod(S4Vectors:::`column<-`, "SDFLWrapperForTransform", 45 | function(x, name, value) 46 | { 47 | x[[name]] <- value 48 | x 49 | }) 50 | 51 | setMethod("as.env", "SDFLWrapperForTransform", 52 | function(x, enclos = parent.frame(2)) { 53 | env <- S4Vectors:::makeEnvForNames(x, colnames(x), enclos) 54 | S4Vectors:::addSelfRef(x@delegate, env) 55 | }) 56 | 57 | transform.SplitDataFrameList <- function(`_data`, ...) { 58 | illConceivedWrapper <- new("SDFLWrapperForTransform", delegate=`_data`) 59 | transform.DataFrame(illConceivedWrapper, ...)@delegate 60 | } 61 | 62 | setMethod("transform", "SplitDataFrameList", transform.SplitDataFrameList) 63 | -------------------------------------------------------------------------------- /R/Hits-class-leftovers.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### IMPORTANT NOTE - 4/29/2014 3 | ### Most of the stuff that used to be in the IRanges/R/Hits-class.R file was 4 | ### moved to the S4Vectors package (to R/Hits-class.R). 5 | ### The stuff that could not be moved there was *temporarily* kept here in 6 | ### Hits-class-leftovers.R but will need to find a new home (in S4Vectors 7 | ### or in IRanges). 8 | ### 9 | 10 | 11 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 12 | ### Coercion 13 | ### 14 | 15 | ### Turn SortedByQueryHits object 'from' into a PartitioningByEnd object that 16 | ### describes the grouping of hits by query. 17 | .from_SortedByQueryHits_to_PartitioningByEnd <- function(from) 18 | PartitioningByEnd(queryHits(from), NG=queryLength(from)) 19 | setAs("SortedByQueryHits", "PartitioningByEnd", 20 | .from_SortedByQueryHits_to_PartitioningByEnd 21 | ) 22 | setAs("SortedByQueryHits", "Partitioning", 23 | .from_SortedByQueryHits_to_PartitioningByEnd 24 | ) 25 | setAs("SortedByQueryHits", "IntegerRanges", 26 | .from_SortedByQueryHits_to_PartitioningByEnd 27 | ) 28 | setAs("SortedByQueryHits", "IRanges", 29 | function(from) 30 | as(.from_SortedByQueryHits_to_PartitioningByEnd(from), "IRanges") 31 | ) 32 | 33 | ### Turn SortedByQueryHits object 'from' into a CompressedIntegerList object 34 | ### with one list element per element in the original query. 35 | .from_SortedByQueryHits_to_CompressedIntegerList <- function(from) 36 | { 37 | ans_partitioning <- .from_SortedByQueryHits_to_PartitioningByEnd(from) 38 | relist(subjectHits(from), ans_partitioning) 39 | } 40 | setAs("SortedByQueryHits", "CompressedIntegerList", 41 | .from_SortedByQueryHits_to_CompressedIntegerList 42 | ) 43 | setAs("SortedByQueryHits", "IntegerList", 44 | .from_SortedByQueryHits_to_CompressedIntegerList 45 | ) 46 | setAs("SortedByQueryHits", "List", 47 | .from_SortedByQueryHits_to_CompressedIntegerList 48 | ) 49 | 50 | .as.list.SortedByQueryHits <- function(x) 51 | as.list(.from_SortedByQueryHits_to_CompressedIntegerList(x)) 52 | setMethod("as.list", "SortedByQueryHits", .as.list.SortedByQueryHits) 53 | 54 | .from_Hits_to_CompressedIntegerList <- function(from) 55 | { 56 | as(as(from, "SortedByQueryHits"), "CompressedIntegerList") 57 | } 58 | 59 | setAs("Hits", "List", .from_Hits_to_CompressedIntegerList) 60 | setAs("Hits", "IntegerList", .from_Hits_to_CompressedIntegerList) 61 | setAs("Hits", "CompressedIntegerList", .from_Hits_to_CompressedIntegerList) 62 | 63 | setMethod("as.list", "Hits", function(x) as.list(as(x, "SortedByQueryHits"))) 64 | 65 | setAs("Hits", "Grouping", 66 | function(from) ManyToManyGrouping(as(from, "List"), nobj=nRnode(from))) 67 | -------------------------------------------------------------------------------- /R/IPosList-class.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### IPosList objects 3 | ### ------------------------------------------------------------------------- 4 | 5 | 6 | setClass("IPosList", 7 | contains=c("PosList", "IntegerRangesList"), 8 | representation("VIRTUAL"), 9 | prototype(elementType="IPos") 10 | ) 11 | 12 | setClass("SimpleIPosList", 13 | contains=c("IPosList", "SimplePosList", "SimpleIntegerRangesList") 14 | ) 15 | 16 | -------------------------------------------------------------------------------- /R/IPosRanges-comparison.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### Comparing and ordering the ranges in IPosRanges derivatives 3 | ### ------------------------------------------------------------------------- 4 | ### 5 | 6 | 7 | setMethod("pcompareRecursively", "IPosRanges", function(x) FALSE) 8 | 9 | 10 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 11 | ### pcompare() 12 | ### 13 | ### Ranges are ordered by starting position first and then by width. 14 | ### This way, the space of ranges is totally ordered. 15 | ### This "pcompare" method returns one of the 13 predefined codes (>= -6 and 16 | ### <= 6) described in the man page. The signs of those codes reflect this 17 | ### order. 18 | ### 19 | 20 | setMethod("pcompare", c("IPosRanges", "IPosRanges"), 21 | function(x, y) 22 | { 23 | .Call2("C_pcompare_IPosRanges", 24 | start(x), width(x), start(y), width(y), 25 | PACKAGE="IRanges") 26 | } 27 | ) 28 | 29 | rangeComparisonCodeToLetter <- function(code) 30 | { 31 | if (!is.integer(code)) 32 | stop("'code' must be an integer vector") 33 | code <- code + 7L 34 | code[code < 1L | 14L < code] <- 14L 35 | levels <- c(letters[1:13], "X") 36 | structure(code, levels=levels, class="factor") 37 | } 38 | 39 | 40 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 41 | ### match() 42 | ### 43 | 44 | setMethod("match", c("IPosRanges", "IPosRanges"), 45 | function(x, table, nomatch=NA_integer_, incomparables=NULL, 46 | method=c("auto", "quick", "hash")) 47 | { 48 | if (!is.null(incomparables)) 49 | stop("\"match\" method for IPosRanges objects ", 50 | "only accepts 'incomparables=NULL'") 51 | ## Equivalent to (but faster than): 52 | ## findOverlaps(x, table, type="equal", select="first") 53 | ## except when 'x' or 'table' contain empty ranges. 54 | matchIntegerPairs(start(x), width(x), 55 | start(table), width(table), 56 | nomatch=nomatch, method=method) 57 | } 58 | ) 59 | 60 | 61 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 62 | ### selfmatch() 63 | ### 64 | 65 | setMethod("selfmatch", "IPosRanges", 66 | function(x, method=c("auto", "quick", "hash")) 67 | selfmatchIntegerPairs(start(x), width(x), method=method) 68 | ) 69 | 70 | 71 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 72 | ### order() and related methods. 73 | ### 74 | ### is.unsorted(), order(), sort(), rank() on IPosRanges derivatives are 75 | ### consistent with the order implied by pcompare(). 76 | ### is.unsorted() is a quick/cheap way of checking whether an IPosRanges 77 | ### derivative is already sorted, e.g., called prior to a costly sort. 78 | ### sort() and rank() will work out-of-the-box on an IPosRanges derivative 79 | ### thanks to the method for List objects (which delegates to the method for 80 | ### Vector objects). 81 | ### 82 | 83 | .IPosRanges_as_integer_pairs <- function(x) 84 | { 85 | a <- start(x) 86 | b <- width(x) 87 | list(a, b) 88 | } 89 | 90 | setMethod("is.unsorted", "IPosRanges", 91 | function(x, na.rm=FALSE, strictly=FALSE) 92 | { 93 | if (!identical(na.rm, FALSE)) 94 | warning("\"is.unsorted\" method for IPosRanges objects ", 95 | "ignores the 'na.rm' argument") 96 | if (!isTRUEorFALSE(strictly)) 97 | stop("'strictly' must be TRUE of FALSE") 98 | ## It seems that creating the integer pairs below is faster when 99 | ## 'x' is already sorted (TODO: Investigate why). Therefore, and 100 | ## somewhat counterintuitively, is.unsorted() can be faster when 'x' 101 | ## is already sorted (which, in theory, is the worst-case scenario 102 | ## because S4Vectors:::sortedIntegerPairs() will then need to take a 103 | ## full walk on 'x') than when it is unsorted (in which case 104 | ## S4Vectors:::sortedIntegerPairs() might stop walking on 'x' after 105 | ## checking its first 2 elements only -- the best-case scenario). 106 | pairs <- .IPosRanges_as_integer_pairs(x) 107 | !S4Vectors:::sortedIntegerPairs(pairs[[1L]], pairs[[2L]], 108 | strictly=strictly) 109 | } 110 | ) 111 | 112 | .order_IPosRanges <- function(x, decreasing=FALSE) 113 | { 114 | if (!isTRUEorFALSE(decreasing)) 115 | stop("'decreasing' must be TRUE or FALSE") 116 | pairs <- .IPosRanges_as_integer_pairs(x) 117 | orderIntegerPairs(pairs[[1L]], pairs[[2L]], decreasing=decreasing) 118 | } 119 | 120 | ### 'na.last' is pointless (IPosRanges derivatives don't contain NAs) so is 121 | ### ignored. 122 | ### 'method' is also ignored at the moment. 123 | setMethod("order", "IPosRanges", 124 | function(..., na.last=TRUE, decreasing=FALSE, 125 | method=c("auto", "shell", "radix")) 126 | { 127 | ## Turn off this warning for now since it triggers spurious warnings 128 | ## when calling sort() on an IPosRangesList derivative. The root of 129 | ## the problem is inconsistent defaults for 'na.last' between order() 130 | ## and sort(), as reported here: 131 | ## https://stat.ethz.ch/pipermail/r-devel/2015-November/072012.html 132 | #if (!identical(na.last, TRUE)) 133 | # warning("\"order\" method for IPosRanges objects ", 134 | # "ignores the 'na.last' argument") 135 | if (!isTRUEorFALSE(decreasing)) 136 | stop("'decreasing' must be TRUE or FALSE") 137 | ## All arguments in '...' are guaranteed to be IPosRanges derivatives. 138 | args <- list(...) 139 | if (length(args) == 1L) 140 | return(.order_IPosRanges(args[[1L]], decreasing)) 141 | order_args <- c(unlist(lapply(args, .IPosRanges_as_integer_pairs), 142 | recursive=FALSE, use.names=FALSE), 143 | list(na.last=na.last, decreasing=decreasing)) 144 | do.call(order, order_args) 145 | } 146 | ) 147 | 148 | -------------------------------------------------------------------------------- /R/RangedSelection-class.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### Selection of features and columns by intervals and column names 3 | ### ------------------------------------------------------------------------- 4 | 5 | setClass("RangedSelection", 6 | representation(ranges = "IntegerRangesList", colnames = "character")) 7 | 8 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 9 | ### Accessor methods. 10 | ### 11 | 12 | setMethod("ranges", "RangedSelection", 13 | function(x, use.names=TRUE, use.mcols=FALSE) x@ranges 14 | ) 15 | setReplaceMethod("ranges", "RangedSelection", 16 | function(x, value) { 17 | x@ranges <- value 18 | x 19 | }) 20 | 21 | setMethod("colnames", "RangedSelection", 22 | function(x, do.NULL = TRUE, prefix = "col") x@colnames) 23 | setReplaceMethod("colnames", "RangedSelection", 24 | function(x, value) { 25 | x@colnames <- value 26 | x 27 | }) 28 | 29 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 30 | ### Constructor. 31 | ### 32 | 33 | RangedSelection <- function(ranges = IRangesList(), colnames = character()) { 34 | if (!is(ranges, "IntegerRangesList")) 35 | stop("'ranges' must be an IntegerRangesList") 36 | if (!is.character(colnames) || S4Vectors:::anyMissing(colnames)) 37 | stop("'colnames' must be a character vector without missing values") 38 | new("RangedSelection", ranges = ranges, colnames = colnames) 39 | } 40 | 41 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 42 | ### Coercion. 43 | ### 44 | 45 | setAs("IntegerRangesList", "RangedSelection", 46 | function(from) RangedSelection(from) 47 | ) 48 | 49 | -------------------------------------------------------------------------------- /R/Rle-class-leftovers.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### IMPORTANT NOTE - 7/2/2014 3 | ### Most of the stuff that used to be in the IRanges/R/Rle-class.R file was 4 | ### moved to the S4Vectors package (to R/Rle-class.R and R/Rle-utils.R). 5 | ### The stuff that could not be moved there was *temporarily* kept here in 6 | ### Rle-class-leftovers.R but will need to find a new home (in S4Vectors 7 | ### or in IRanges). 8 | ### 9 | 10 | 11 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 12 | ### Accessor methods. 13 | ### 14 | 15 | setMethod("ranges", "Rle", 16 | function(x, use.names=TRUE, use.mcols=FALSE) 17 | IRanges(start(x), width=width(x)) 18 | ) 19 | 20 | 21 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 22 | ### Coercion 23 | ### 24 | 25 | setAs("Rle", "IRanges", 26 | function(from) 27 | { 28 | if (!is.logical(runValue(from)) || S4Vectors:::anyMissing(runValue(from))) 29 | stop("cannot coerce a non-logical 'Rle' or a logical 'Rle' ", 30 | "with NAs to an IRanges object") 31 | keep <- runValue(from) 32 | ## The returned IRanges instance is guaranteed to be normal. 33 | ans_start <- start(from)[keep] 34 | ans_width <- runLength(from)[keep] 35 | new2("IRanges", start=ans_start, width=ans_width, check=FALSE) 36 | }) 37 | 38 | setAs("Rle", "NormalIRanges", 39 | function(from) newNormalIRangesFromIRanges(as(from, "IRanges"), check=FALSE)) 40 | 41 | 42 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 43 | ### General methods 44 | ### 45 | 46 | setGeneric("findRange", signature = "vec", 47 | function(x, vec) standardGeneric("findRange")) 48 | 49 | setMethod("findRange", signature = c(vec = "Rle"), 50 | function(x, vec) { 51 | run <- findRun(x, vec) 52 | if (S4Vectors:::anyMissing(run)) 53 | stop("all 'x' values must be in [1, 'length(vec)']") 54 | IRanges(start = start(vec)[run], width = width(vec)[run], 55 | names = names(x)) 56 | }) 57 | 58 | setGeneric("orderAsRanges", signature = c("x"), # not exported 59 | function(x, na.last = TRUE, decreasing = FALSE) 60 | standardGeneric("orderAsRanges")) 61 | 62 | setMethod("orderAsRanges", "Rle", 63 | function(x, na.last = TRUE, decreasing = FALSE) 64 | { 65 | ord <- base::order(runValue(x), na.last = na.last, 66 | decreasing = decreasing) 67 | new2("IRanges", start = start(x)[ord], width = runLength(x)[ord], 68 | check = FALSE) 69 | }) 70 | 71 | setGeneric("splitRanges", signature = "x", 72 | function(x) standardGeneric("splitRanges")) 73 | 74 | setMethod("splitRanges", "Rle", 75 | function(x) { 76 | split(IRanges(start = start(x), width = runLength(x)), 77 | runValue(x)) 78 | }) 79 | 80 | setMethod("splitRanges", "vector_OR_factor", 81 | function(x) { 82 | callGeneric(Rle(x)) 83 | }) 84 | 85 | -------------------------------------------------------------------------------- /R/RleViews-class.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### RleViews objects 3 | ### ------------------------------------------------------------------------- 4 | ### 5 | 6 | 7 | ### The RleViews class is the basic container for storing a set of views 8 | ### (start/end locations) on the same Rle object, called the "subject" 9 | ### vector. 10 | setClass("RleViews", 11 | contains=c("Views", "RleList"), 12 | representation( 13 | subject="Rle" 14 | ) 15 | ) 16 | 17 | 18 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 19 | ### User-friendly constructor. 20 | ### 21 | 22 | setMethod("Views", "Rle", 23 | function(subject, start=NULL, end=NULL, width=NULL, names=NULL) 24 | new_Views(subject, 25 | start=start, end=end, width=width, names=names, 26 | Class="RleViews") 27 | ) 28 | 29 | 30 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 31 | ### Coercion. 32 | ### 33 | 34 | setAs("AtomicList", "RleViews", function(from) { 35 | to <- Views(as(unlist(from, use.names = FALSE), "Rle"), 36 | PartitioningByEnd(from)) 37 | names(to) <- names(from) 38 | to 39 | }) 40 | 41 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 42 | ### The "show" method. 43 | ### 44 | 45 | ### The 2 helper functions below convert a given view on an Rle object 46 | ### into a character-string. 47 | ### Both assume that 'start' <= 'end' (so they don't check it) and 48 | ### padd the result with spaces to produce the "margin effect" 49 | ### if 'start' or 'end' are out of limits. 50 | 51 | RleViews.show_vframe_header <- function(iW, startW, endW, widthW) 52 | { 53 | cat(format("", width=iW+1), 54 | format("start", width=startW, justify="right"), " ", 55 | format("end", width=endW, justify="right"), " ", 56 | format("width", width=widthW, justify="right"), "\n", 57 | sep="") 58 | } 59 | 60 | RleViews.show_vframe_line <- function(x, i, iW, startW, endW, widthW) 61 | { 62 | lsx <- length(subject(x)) 63 | start <- start(x)[i] 64 | end <- end(x)[i] 65 | width <- end - start + 1 66 | snippetWidth <- getOption("width") - 10 - iW - startW - endW - widthW 67 | if (width > 0 && lsx > 0 && start <= lsx && end >= 1) { 68 | snippetStart <- max(min(start,lsx),1) 69 | snippetEnd <- max(min(end,lsx,start + snippetWidth),1) 70 | snippet <- 71 | format(as.vector(extractROWS(subject(x), 72 | IRanges(snippetStart, snippetEnd)))) 73 | snippet <- snippet[cumsum(nchar(snippet) + 1L) < snippetWidth] 74 | if (length(snippet) < width) { 75 | snippet <- c(snippet, "...") 76 | } 77 | snippet <- paste(snippet, collapse = " ") 78 | } else { 79 | snippet <- " " 80 | } 81 | cat(format(paste("[", i,"]", sep=""), width=iW, justify="right"), " ", 82 | format(start, width=startW, justify="right"), " ", 83 | format(end, width=endW, justify="right"), " ", 84 | format(width, width=widthW, justify="right"), " ", 85 | "[", snippet, "]\n", 86 | sep="") 87 | } 88 | 89 | ### 'half_nrow' must be >= 1 90 | RleViews.show_vframe <- function(x, half_nrow=9L) 91 | { 92 | cat("\nviews:") 93 | lx <- length(x) 94 | if (lx == 0) 95 | cat(" NONE\n") 96 | else { 97 | cat("\n") 98 | iW <- nchar(as.character(lx)) + 2 # 2 for the brackets 99 | startMax <- max(start(x)) 100 | startW <- max(nchar(startMax), nchar("start")) 101 | endMax <- max(end(x)) 102 | endW <- max(nchar(endMax), nchar("end")) 103 | widthMax <- max(width(x)) 104 | widthW <- max(nchar(widthMax), nchar("width")) 105 | RleViews.show_vframe_header(iW, startW, endW, widthW) 106 | if (lx <= 2*half_nrow+1) { 107 | for (i in seq_len(lx)) 108 | RleViews.show_vframe_line(x, i, iW, startW, endW, widthW) 109 | } else { 110 | for (i in 1:half_nrow) 111 | RleViews.show_vframe_line(x, i, iW, startW, endW, widthW) 112 | cat(format("...", width=iW, justify="right"), 113 | " ", 114 | format("...", width=startW, justify="right"), 115 | " ", 116 | format("...", width=endW, justify="right"), 117 | " ", 118 | format("...", width=widthW, justify="right"), 119 | " ...\n", sep="") 120 | for (i in (lx-half_nrow+1L):lx) 121 | RleViews.show_vframe_line(x, i, iW, startW, endW, widthW) 122 | } 123 | } 124 | } 125 | 126 | setMethod("show", "RleViews", 127 | function(object) 128 | { 129 | cat("Views on a ", length(subject(object)), "-length Rle subject\n", sep="") 130 | RleViews.show_vframe(object) 131 | } 132 | ) 133 | -------------------------------------------------------------------------------- /R/RleViews-utils.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### View summarization methods for RleViews objects 3 | ### ------------------------------------------------------------------------- 4 | 5 | 6 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 7 | ### viewApply() method for RleViews objects 8 | ### 9 | 10 | setMethod("viewApply", "RleViews", 11 | function(X, FUN, ..., simplify = TRUE) { 12 | X <- trim(X) 13 | ans <- 14 | aggregate(subject(X), start = structure(start(X), names = names(X)), 15 | end = end(X), FUN = FUN, ..., simplify = simplify) 16 | if (!simplify) { 17 | ans <- S4Vectors:::new_SimpleList_from_list("SimpleList", 18 | ans, 19 | metadata=metadata(X), 20 | mcols=mcols(X)) 21 | } 22 | ans 23 | }) 24 | 25 | 26 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 27 | ### viewMins(), viewMaxs(), viewSums(), viewMeans(), viewWhichMins(), and 28 | ### viewWhichMaxs() methods for RleViews objects 29 | ### 30 | 31 | ### Coerce 'x' to integer if all its values are within the integer range. 32 | .double_to_integer_if_in_range <- function(x) 33 | { 34 | stopifnot(is.double(x)) 35 | x_min <- suppressWarnings(min(x, na.rm=TRUE)) 36 | x_max <- suppressWarnings(max(x, na.rm=TRUE)) 37 | int_max_plus_one <- .Machine$integer.max + 1 38 | if (-int_max_plus_one < x_min && x_max < int_max_plus_one) 39 | x <- setNames(as.integer(x), names(x)) 40 | x 41 | } 42 | 43 | .C_summarize_RleViews <- function(op, x_subject, x_ranges, na.rm) 44 | { 45 | C_ans <- .Call2("C_summarize_RleViews", op, x_subject, x_ranges, na.rm, 46 | PACKAGE="IRanges") 47 | if (op == "sum") { 48 | run_vals <- runValue(x_subject) 49 | if (is.integer(run_vals) || is.logical(run_vals)) 50 | C_ans <- .double_to_integer_if_in_range(C_ans) 51 | } 52 | C_ans 53 | } 54 | 55 | .summarize_RleViews <- function(op, x, na.rm=FALSE) 56 | { 57 | stopifnot(isSingleString(op), is(x, "RleViews"), isTRUEorFALSE(na.rm)) 58 | x <- trim(x) 59 | x_ranges <- ranges(x) 60 | x_subject <- subject(x) 61 | run_vals <- runValue(x_subject) 62 | if (!is.complex(run_vals)) 63 | return(.C_summarize_RleViews(op, x_subject, x_ranges, na.rm)) 64 | if (op %in% c("min", "max", "which.min", "which.max")) 65 | stop(wmsg("operation not supported when the subject ", 66 | "is an Rle that contains \"complex\" values")) 67 | ans_names <- names(x_ranges) 68 | x_ranges <- unname(x_ranges) 69 | ans_r <- .C_summarize_RleViews(op, Re(x_subject), x_ranges, na.rm) 70 | ans_i <- .C_summarize_RleViews(op, Im(x_subject), x_ranges, na.rm) 71 | setNames(complex(real=ans_r, imaginary=ans_i), ans_names) 72 | } 73 | 74 | setMethod("viewMins", "RleViews", 75 | function(x, na.rm=FALSE) .summarize_RleViews("min", x, na.rm=na.rm) 76 | ) 77 | 78 | setMethod("viewMaxs", "RleViews", 79 | function(x, na.rm=FALSE) .summarize_RleViews("max", x, na.rm=na.rm) 80 | ) 81 | 82 | setMethod("viewSums", "RleViews", 83 | function(x, na.rm=FALSE) .summarize_RleViews("sum", x, na.rm=na.rm) 84 | ) 85 | 86 | setMethod("viewMeans", "RleViews", 87 | function(x, na.rm=FALSE) .summarize_RleViews("mean", x, na.rm=na.rm) 88 | ) 89 | 90 | ### Even though base::which(), base::which.min(), and base::which.max() always 91 | ### ignore NAs and don't have an 'na.rm' argument to control that, somehow 92 | ### someone felt it could be a good idea to give the viewWhichMins() and 93 | ### viewWhichMaxs() generics an 'na.rm' argument, not sure why. Plus, the 94 | ### old implementations (from IRanges < 2.41.3) of the viewWhichMins() and 95 | ### viewWhichMaxs() methods for RleViews objects (which were based on old .Call 96 | ### entry points C_viewWhichMins_RleViews and C_viewWhichMaxs_RleViews) were 97 | ### apparently trying to support the 'na.rm' argument but that support was 98 | ### broken. 99 | setMethod("viewWhichMins", "RleViews", 100 | function(x, na.rm=FALSE) 101 | { 102 | if (!identical(na.rm, FALSE)) 103 | warning(wmsg("the viewWhichMins() method for RleViews objects ", 104 | "always ignores NAs (the 'na.rm' argument has ", 105 | "no effect)")) 106 | .summarize_RleViews("which.min", x) 107 | } 108 | ) 109 | 110 | setMethod("viewWhichMaxs", "RleViews", 111 | function(x, na.rm=FALSE) 112 | { 113 | if (!identical(na.rm, FALSE)) 114 | warning(wmsg("the viewWhichMaxs() method for RleViews objects ", 115 | "always ignores NAs (the 'na.rm' argument has ", 116 | "no effect)")) 117 | .summarize_RleViews("which.max", x) 118 | } 119 | ) 120 | 121 | 122 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 123 | ### viewRangeMins() and viewRangeMaxs() methods for RleViews objects 124 | ### 125 | 126 | setMethod("viewRangeMins", "RleViews", 127 | function(x, na.rm=FALSE) 128 | { 129 | if (!identical(na.rm, FALSE)) 130 | warning(wmsg("the viewRangeMins() method for RleViews objects ", 131 | "always ignores NAs (the 'na.rm' argument has ", 132 | "no effect)")) 133 | mins <- viewWhichMins(x) 134 | pintersect(findRange(mins, subject(x)), trim(x)) 135 | } 136 | ) 137 | 138 | setMethod("viewRangeMaxs", "RleViews", 139 | function(x, na.rm=FALSE) 140 | { 141 | if (!identical(na.rm, FALSE)) 142 | warning(wmsg("the viewRangeMaxs() method for RleViews objects ", 143 | "always ignores NAs (the 'na.rm' argument has ", 144 | "no effect)")) 145 | maxs <- viewWhichMaxs(x) 146 | pintersect(findRange(maxs, subject(x)), trim(x)) 147 | } 148 | ) 149 | 150 | -------------------------------------------------------------------------------- /R/RleViewsList-class.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### RleViewsList objects 3 | ### ------------------------------------------------------------------------- 4 | 5 | setClass("RleViewsList", representation("VIRTUAL"), 6 | prototype = prototype(elementType = "RleViews"), 7 | contains = "ViewsList") 8 | setClass("SimpleRleViewsList", 9 | prototype = prototype(elementType = "RleViews"), 10 | contains = c("RleViewsList", "SimpleViewsList")) 11 | 12 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 13 | ### Accessor. 14 | ### 15 | 16 | setMethod("subject", "SimpleRleViewsList", 17 | function(x) 18 | S4Vectors:::new_SimpleList_from_list("SimpleRleList", 19 | lapply(x, slot, "subject")) 20 | ) 21 | 22 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 23 | ### Constructor. 24 | ### 25 | 26 | setMethod("Views", "RleList", 27 | function(subject, start=NULL, end=NULL, width=NULL, names=NULL) 28 | RleViewsList(rleList = subject, rangesList = start)) 29 | 30 | RleViewsList <- function(..., rleList, rangesList) 31 | { 32 | views <- list(...) 33 | if (!missing(rleList) && !missing(rangesList)) { 34 | if (length(views) > 0) 35 | stop(wmsg("'...' must be empty when 'rleList' and 'rangesList' ", 36 | "are specified")) 37 | if (!is(rleList, "RleList")) 38 | stop(wmsg("'rleList' must be a RleList object")) 39 | if (!is(rangesList, "IntegerRangesList")) { 40 | rangesList <- try(IRangesList(rangesList), silent = TRUE) 41 | if (inherits(rangesList, "try-error")) 42 | stop(wmsg("'rangesList' must be a IntegerRangesList object")) 43 | } 44 | if (length(rleList) != length(rangesList)) 45 | stop("'rleList' and 'rangesList' must have the same length") 46 | rleList_names <- names(rleList) 47 | rangesList_names <- names(rangesList) 48 | if (!(is.null(rleList_names) || 49 | is.null(rangesList_names) || 50 | identical(rleList_names, rangesList_names))) { 51 | if (anyDuplicated(rleList_names,) || 52 | anyDuplicated(rangesList_names)) 53 | stop(wmsg("when both 'rleList' and 'rangesList' have names, ", 54 | "the names on each object cannot have duplicates")) 55 | if (!setequal(rleList_names, rangesList_names)) 56 | stop(wmsg("when both 'rleList' and 'rangesList' have names, ", 57 | "the set of names must be the same on each object")) 58 | warning(wmsg("'rleList' was reordered so that its names ", 59 | "match the names on 'rangesList'")) 60 | rleList <- rleList[rangesList_names] 61 | } 62 | views <- Map(Views, rleList, rangesList) 63 | } else if ((length(views) > 0) && 64 | (!missing(rleList) || !missing(rangesList))) { 65 | stop(wmsg("cannot specify 'rleList' or 'rangesList' ", 66 | "when specifying '...'")) 67 | } else { 68 | if (length(views) == 1 && is.list(views[[1L]])) 69 | views <- views[[1L]] 70 | if (!all(sapply(views, is, "RleViews"))) 71 | stop(wmsg("all elements in '...' must be RleViews objects")) 72 | } 73 | S4Vectors:::new_SimpleList_from_list("SimpleRleViewsList", views) 74 | } 75 | 76 | 77 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 78 | ### Coercion. 79 | ### 80 | 81 | setAs("RleViewsList", "SimpleIRangesList", function(from) 82 | IRangesList(lapply(from, as, "IRanges"), compress=FALSE)) 83 | 84 | setAs("RleViewsList", "IRangesList", 85 | function(from) as(from, "SimpleIRangesList")) 86 | 87 | -------------------------------------------------------------------------------- /R/RleViewsList-utils.R: -------------------------------------------------------------------------------- 1 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 | ### The "viewApply", "viewMins", "viewMaxs", and "viewSums" generics and 3 | ### methods. 4 | ### 5 | 6 | setMethod("viewApply", "RleViewsList", 7 | function(X, FUN, ..., simplify = TRUE) { 8 | ans_listData <- lapply(structure(seq_along(X), names=names(X)), 9 | function(i) { 10 | ans_elt <- aggregate( 11 | subject(X[[i]]), 12 | start=structure(start(X[[i]]), 13 | names=names(start(X[[i]]))), 14 | end=end(X[[i]]), 15 | FUN=FUN, 16 | ..., 17 | simplify=simplify) 18 | if (!simplify) 19 | ans_elt <- S4Vectors:::new_SimpleList_from_list("SimpleList", 20 | ans_elt, 21 | metadata=metadata(X[[i]]), 22 | mcols=mcols(X[[i]], use.names=FALSE)) 23 | ans_elt 24 | }) 25 | S4Vectors:::new_SimpleList_from_list("SimpleList", ans_listData, 26 | metadata=metadata(X), 27 | mcols=mcols(X, use.names=FALSE))}) 28 | 29 | .summaryRleViewsList <- function(x, FUN, na.rm = FALSE, outputListType = NULL) 30 | { 31 | FUN <- match.fun(FUN) 32 | if (length(x) == 0) { 33 | outputListType <- "SimpleList" 34 | listData <- list() 35 | } else { 36 | if (is.null(outputListType)) { 37 | valuesClass <- class(runValue(subject(x[[1L]]))) 38 | if (valuesClass == "integer" || valuesClass == "logical") 39 | outputListType <- "SimpleIntegerList" 40 | else if (valuesClass == "numeric") 41 | outputListType <- "SimpleNumericList" 42 | else 43 | stop("cannot compute numeric summary over a non-numeric Rle") 44 | } 45 | listData <- 46 | lapply(structure(seq_len(length(x)), names = names(x)), 47 | function(i) FUN(x[[i]], na.rm = na.rm)) 48 | } 49 | S4Vectors:::new_SimpleList_from_list(outputListType, listData, 50 | metadata = metadata(x), 51 | mcols = mcols(x, use.names=FALSE)) 52 | } 53 | setMethod("viewMins", "RleViewsList", 54 | function(x, na.rm = FALSE) 55 | .summaryRleViewsList(x, FUN = viewMins, na.rm = na.rm)) 56 | 57 | setMethod("viewMaxs", "RleViewsList", 58 | function(x, na.rm = FALSE) 59 | .summaryRleViewsList(x, FUN = viewMaxs, na.rm = na.rm)) 60 | 61 | setMethod("viewSums", "RleViewsList", 62 | function(x, na.rm = FALSE) 63 | .summaryRleViewsList(x, FUN = viewSums, na.rm = na.rm)) 64 | 65 | setMethod("viewMeans", "RleViewsList", 66 | function(x, na.rm = FALSE) 67 | .summaryRleViewsList(x, FUN = viewMeans, na.rm = na.rm, 68 | outputListType = "SimpleNumericList")) 69 | 70 | setMethod("viewWhichMins", "RleViewsList", 71 | function(x, na.rm = FALSE) 72 | .summaryRleViewsList(x, FUN = viewWhichMins, na.rm = na.rm, 73 | outputListType = "SimpleIntegerList")) 74 | 75 | setMethod("viewWhichMaxs", "RleViewsList", 76 | function(x, na.rm = FALSE) 77 | .summaryRleViewsList(x, FUN = viewWhichMaxs, na.rm = na.rm, 78 | outputListType = "SimpleIntegerList")) 79 | 80 | setMethod("viewRangeMaxs", "RleViewsList", 81 | function(x, na.rm = FALSE) 82 | .summaryRleViewsList(x, FUN = viewRangeMaxs, na.rm = na.rm, 83 | outputListType = "SimpleIRangesList")) 84 | 85 | setMethod("viewRangeMins", "RleViewsList", 86 | function(x, na.rm = FALSE) 87 | .summaryRleViewsList(x, FUN = viewRangeMins, na.rm = na.rm, 88 | outputListType = "SimpleIRangesList")) 89 | -------------------------------------------------------------------------------- /R/SimpleGrouping-class.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### Grouping objects implemented with an IntegerList 3 | ### ------------------------------------------------------------------------- 4 | 5 | setClass("SimpleGrouping", 6 | ### TODO: contain VIRTUAL after R 3.4 release 7 | contains=c("Grouping", "SimpleIntegerList")) 8 | 9 | setClass("SimpleManyToOneGrouping", 10 | contains=c("ManyToOneGrouping", "SimpleGrouping")) 11 | 12 | setClass("BaseManyToManyGrouping", 13 | representation(nobj="integer"), 14 | ### TODO: contain VIRTUAL after R 3.4 release 15 | contains="ManyToManyGrouping", 16 | validity=function(object) { 17 | if (!isSingleNumber(object@nobj)) 18 | "'nobj' must be a single, non-NA number" 19 | }) 20 | 21 | setClass("SimpleManyToManyGrouping", 22 | contains=c("BaseManyToManyGrouping", "SimpleGrouping")) 23 | 24 | ### ------------------------------------------------------------------------- 25 | ### Grouping API implementation 26 | ### ---------------------------- 27 | ### 28 | 29 | setMethod("nobj", "BaseManyToManyGrouping", function(x) x@nobj) 30 | 31 | ### ------------------------------------------------------------------------- 32 | ### Constructors 33 | ### ---------------------------- 34 | ### 35 | 36 | ManyToOneGrouping <- function(..., compress=TRUE) { 37 | CompressedOrSimple <- if (compress) "Compressed" else "Simple" 38 | Class <- paste0(CompressedOrSimple, "ManyToOneGrouping") 39 | new(Class, IntegerList(..., compress=compress)) 40 | } 41 | 42 | ManyToManyGrouping <- function(..., nobj, compress=TRUE) { 43 | CompressedOrSimple <- if (compress) "Compressed" else "Simple" 44 | Class <- paste0(CompressedOrSimple, "ManyToManyGrouping") 45 | new(Class, IntegerList(..., compress=compress), nobj=nobj) 46 | } 47 | 48 | ### ------------------------------------------------------------------------- 49 | ### Coercion 50 | ### ---------------------------- 51 | ### 52 | 53 | setOldClass(c("grouping", "integer")) 54 | 55 | ## utils::relist dipatches only on 'skeleton' so this is here instead of in R 56 | setMethod("relist", c("grouping", "missing"), function(flesh, skeleton) { 57 | relist(as.integer(flesh), PartitioningByEnd(attr(flesh, "ends"))) 58 | }) 59 | 60 | setMethod("split", c("ANY", "ManyToOneGrouping"), function(x, f, drop=FALSE) { 61 | stopifnot(isTRUEorFALSE(drop)) 62 | ans <- extractList(x, f) 63 | if (drop) { 64 | ans <- ans[lengths(ans) > 0L] 65 | } 66 | ans 67 | }) 68 | 69 | setAs("grouping", "Grouping", function(from) { 70 | as(from, "ManyToOneGrouping") 71 | }) 72 | 73 | setAs("grouping", "ManyToOneGrouping", function(from) { 74 | ManyToOneGrouping(relist(from), compress=TRUE) 75 | }) 76 | 77 | setAs("vector", "Grouping", function(from) { 78 | if (anyNA(from)) 79 | as(from, "ManyToManyGrouping") 80 | else as(from, "ManyToOneGrouping") 81 | }) 82 | 83 | setAs("vector", "ManyToOneGrouping", function(from) { 84 | to <- as(grouping(from), "Grouping") 85 | names(to) <- from[unlist(to)[end(PartitioningByEnd(to))]] 86 | to 87 | }) 88 | 89 | setAs("factor", "ManyToOneGrouping", function(from) { 90 | ManyToOneGrouping(splitAsList(seq_along(from), from)) 91 | }) 92 | 93 | setAs("vector", "ManyToManyGrouping", function(from) { 94 | g <- as(from, "ManyToOneGrouping") 95 | if (anyNA(from)) 96 | g <- g[-length(g)] 97 | ManyToManyGrouping(g, nobj=length(from)) 98 | }) 99 | 100 | setAs("ManyToOneGrouping", "factor", function(from) { 101 | levels <- if (!is.null(names(from))) { 102 | names(from) 103 | } else { 104 | as.character(seq_along(from)) 105 | } 106 | structure(togroup(from), levels=levels, class="factor") 107 | }) 108 | 109 | setMethod("as.factor", "ManyToOneGrouping", function(x) { 110 | as(x, "factor") 111 | }) 112 | 113 | makeGroupNames <- function(x) { 114 | if (is.null(x)) { 115 | x <- character(length(x)) 116 | } 117 | ind <- which(x == "") 118 | x[ind] <- paste("Group", ind, sep = ".") 119 | x 120 | } 121 | 122 | levelCols <- function(by) { 123 | DataFrame(expand.grid(lapply(by, levels))) 124 | } 125 | 126 | setAs("FactorList", "Grouping", function(from) { 127 | l <- as.list(from) 128 | names(l) <- makeGroupNames(names(from)) 129 | as(DataFrame(l), "Grouping") 130 | }) 131 | 132 | setAs("DataFrame", "Grouping", function(from) { 133 | factors <- lapply(from, as.factor) 134 | l <- splitAsList(seq_len(nrow(from)), factors) 135 | mcols(l) <- levelCols(factors) 136 | if (anyNA(from, recursive=TRUE)) { 137 | ManyToManyGrouping(l, nobj=nrow(from)) 138 | } else { 139 | ManyToOneGrouping(l) 140 | } 141 | }) 142 | -------------------------------------------------------------------------------- /R/Vector-class-leftovers.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### IMPORTANT NOTE - 4/29/2014 3 | ### Most of the stuff that used to be in the IRanges/R/Vector-class.R file 4 | ### was moved to the S4Vectors package (to R/Vector-class.R). 5 | ### The stuff that could not be moved there was *temporarily* kept here in 6 | ### Vector-class-leftovers.R but will need to find a new home (in S4Vectors 7 | ### or in IRanges). 8 | ### 9 | 10 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 11 | ### Other subsetting-related operations 12 | ### 13 | 14 | ### S3/S4 combo for window<-.Vector 15 | `window<-.Vector` <- function(x, start=NA, end=NA, width=NA, ..., value) { 16 | window(x, start, end, width, ...) <- value 17 | x 18 | } 19 | `.window<-.Vector` <- function(x, start=NA, end=NA, width=NA, ..., value) 20 | { 21 | i <- solveUserSEWForSingleSeq(NROW(x), start, end, width) 22 | li <- width(i) 23 | if (li == 0L) { 24 | ## Surprisingly, in that case, `[<-` on standard vectors does not 25 | ## even look at 'value'. So neither do we... 26 | return(x) 27 | } 28 | lv <- NROW(value) 29 | if (lv == 0L) 30 | stop("replacement has length zero") 31 | value <- normalizeSingleBracketReplacementValue(value, x) 32 | if (li != lv) { 33 | if (li %% lv != 0L) 34 | warning("number of values supplied is not a sub-multiple ", 35 | "of the number of values to be replaced") 36 | value <- extractROWS(value, rep(seq_len(lv), length.out=li)) 37 | } 38 | c(window(x, end=start(i)-1L), 39 | value, 40 | window(x, start=end(i)+1L)) 41 | } 42 | setReplaceMethod("window", "Vector", `.window<-.Vector`) 43 | 44 | ### S3/S4 combo for window<-.vector 45 | `window<-.vector` <- `window<-.Vector` 46 | setReplaceMethod("window", "vector", `window<-.vector`) 47 | 48 | ### S3/S4 combo for window<-.factor 49 | `window<-.factor` <- function(x, start=NA, end=NA, width=NA, ..., value) 50 | { 51 | levels <- levels(x) 52 | x <- as.character(x) 53 | value <- as.character(value) 54 | factor(callGeneric(), levels=levels) 55 | } 56 | setReplaceMethod("window", "factor", `window<-.factor`) 57 | 58 | 59 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 60 | ### Looping methods 61 | ### 62 | 63 | #.tapplyDefault <- base::tapply 64 | #environment(.tapplyDefault) <- topenv() 65 | .tapplyDefault <- 66 | function(X, INDEX, FUN = NULL, ..., simplify = TRUE) 67 | { 68 | if (!is.null(FUN)) 69 | FUN <- match.fun(FUN) 70 | if (missing(INDEX)) 71 | stop("'INDEX' is missing") 72 | if (!is(INDEX, "RleList")) { 73 | if (!is.list(INDEX) && !is(INDEX, "Rle")) 74 | INDEX <- Rle(INDEX) 75 | INDEX <- RleList(INDEX) 76 | } 77 | nI <- length(INDEX) 78 | namelist <- vector("list", nI) 79 | names(namelist) <- names(INDEX) 80 | extent <- integer(nI) 81 | nx <- NROW(X) 82 | one <- 1L 83 | group <- Rle(one, nx) 84 | ngroup <- one 85 | for (i in seq_len(nI)) { 86 | index <- INDEX[[i]] 87 | if (!is.factor(runValue(index))) 88 | runValue(index) <- factor(runValue(index)) 89 | offset <- index 90 | runValue(offset) <- ngroup * (as.integer(runValue(index)) - one) 91 | if (length(index) != nx) 92 | stop("arguments must have same length") 93 | namelist[[i]] <- levels(index) 94 | extent[i] <- nlevels(index) 95 | group <- group + offset 96 | ngroup <- ngroup * nlevels(index) 97 | } 98 | if (is.null(FUN)) 99 | return(as.vector(group)) 100 | groupRanges <- splitRanges(group) 101 | ans <- lapply(groupRanges, function(i) FUN(extractROWS(X, i), ...)) 102 | index <- as.integer(names(ans)) 103 | if (simplify && all(unlist(lapply(ans, length), use.names=FALSE) == 1L)) { 104 | ansmat <- array(dim = extent, dimnames = namelist) 105 | ans <- unlist(ans, recursive = FALSE) 106 | } 107 | else { 108 | ansmat <- 109 | array(vector("list", prod(extent)), dim = extent, 110 | dimnames = namelist) 111 | } 112 | if (length(index) > 0) { 113 | names(ans) <- NULL 114 | ansmat[index] <- ans 115 | } 116 | ansmat 117 | } 118 | setMethod("tapply", c("Vector", "ANY"), .tapplyDefault) 119 | setMethod("tapply", c("ANY", "Vector"), .tapplyDefault) 120 | setMethod("tapply", c("Vector", "Vector"), .tapplyDefault) 121 | 122 | -------------------------------------------------------------------------------- /R/ViewsList-class.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### ViewsList objects 3 | ### ------------------------------------------------------------------------- 4 | 5 | 6 | setClass("ViewsList", 7 | contains="IntegerRangesList", 8 | representation("VIRTUAL"), 9 | prototype(elementType="Views") 10 | ) 11 | 12 | setClass("SimpleViewsList", 13 | contains=c("ViewsList", "SimpleList"), 14 | representation("VIRTUAL") 15 | ) 16 | 17 | 18 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 19 | ### Accessor methods. 20 | ### 21 | 22 | setMethod("ranges", "SimpleViewsList", 23 | function(x, use.names=TRUE, use.mcols=FALSE) 24 | S4Vectors:::new_SimpleList_from_list("SimpleIRangesList", 25 | lapply(x, ranges, use.names=use.names, use.mcols=use.mcols)) 26 | ) 27 | 28 | setMethod("start", "SimpleViewsList", function(x, ...) start(ranges(x))) 29 | setMethod("end", "SimpleViewsList", function(x, ...) end(ranges(x))) 30 | setMethod("width", "SimpleViewsList", function(x) width(ranges(x))) 31 | 32 | 33 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 34 | ### Coercion 35 | ### 36 | 37 | setMethod("as.matrix", "ViewsList", 38 | function(x, rev = FALSE, use.names = FALSE) 39 | { 40 | if (!isTRUEorFALSE(use.names)) 41 | stop("use.names must be TRUE or FALSE") 42 | if (!is(rev, "List")) 43 | rev <- as(rev, "List") 44 | rev <- S4Vectors:::VH_recycle(rev, x, "rev", "x") 45 | max_width <- max(max(width(restrict(ranges(x), start = 1L)))) 46 | m <- do.call(rbind, mapply(as.matrix, x, rev, 47 | IntegerList(max_width), 48 | SIMPLIFY = FALSE)) 49 | nms <- names(x) 50 | if (!is.null(nms) && use.names) { 51 | nms <- rep(nms, elementNROWS(x)) 52 | rownms <- rownames(m) 53 | if (is.null(rownms)) 54 | rownms <- unlist_as_integer(IRanges(1L, width=elementNROWS(x))) 55 | rownames(m) <- paste(nms, rownms, sep = ".") 56 | } 57 | m 58 | }) 59 | -------------------------------------------------------------------------------- /R/cbind-Rle-methods.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### Binding Rle or RleList objects together 3 | ### ------------------------------------------------------------------------- 4 | 5 | 6 | ### Return a DataFrame object with 1 row per run. Its first column is 7 | ### "runLength" and is followed by 1 column per supplied Rle object. 8 | setMethod("cbind", "Rle", 9 | function(...) 10 | { 11 | args <- list(...) 12 | args_names <- names(args) 13 | if (is.null(args_names)) { 14 | noname_idx <- seq_along(args) 15 | } else { 16 | noname_idx <- which(args_names %in% c("", NA_character_)) 17 | } 18 | if (length(noname_idx) != 0L) 19 | names(args)[noname_idx] <- paste0("V", noname_idx) 20 | ## TODO: Call disjoin() with 'with.revmap=TRUE' and use the revmap 21 | ## to avoid the call to findOverlaps() below. 22 | ans_runs <- disjoin(do.call(c, unname(lapply(args, ranges)))) 23 | DataFrame( 24 | runLength=width(ans_runs), 25 | DataFrame( 26 | lapply(args, function(x) { 27 | run_idx <- findOverlaps(ans_runs, ranges(x), type="within", 28 | select="arbitrary") 29 | runValue(x)[run_idx] 30 | }) 31 | ) 32 | ) 33 | } 34 | ) 35 | 36 | ### The supplied RleList objects are recycled the "mapply way" if necessary. 37 | ### Return a CompressedSplitDataFrameList object parallel to the longest 38 | ### supplied RleList object. 39 | setMethod("cbind", "RleList", 40 | function(...) 41 | { 42 | args <- list(...) 43 | DF_list <- do.call(mapply, c(list(cbind), args, list(SIMPLIFY=FALSE))) 44 | as(DF_list, "CompressedSplitDataFrameList") 45 | } 46 | ) 47 | 48 | -------------------------------------------------------------------------------- /R/multisplit.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### multisplit() 3 | ### ------------------------------------------------------------------------- 4 | ### 5 | 6 | 7 | multisplit <- function(x, f) { 8 | if (!is.list(f) && !is(f, "List")) 9 | stop("'f' must be a list") 10 | if (length(x) != length(f)) 11 | stop("Length of 'f' must equal length of 'x'") 12 | splitAsList(rep(x, elementNROWS(f)), unlist(f, use.names = FALSE)) 13 | } 14 | 15 | -------------------------------------------------------------------------------- /R/range-squeezers.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### Generic functions for squeezing the ranges out of a range-based object 3 | ### ------------------------------------------------------------------------- 4 | 5 | 6 | ### Extract the ranges as an IRanges object. 7 | setGeneric("ranges", signature="x", 8 | function(x, use.names=TRUE, use.mcols=FALSE, ...) 9 | standardGeneric("ranges") 10 | ) 11 | 12 | ### Extract the ranges as an IRangesList object. 13 | setGeneric("rglist", signature="x", 14 | function(x, use.names=TRUE, use.mcols=FALSE, ...) 15 | standardGeneric("rglist") 16 | ) 17 | 18 | ### Pairs method. 19 | setMethod("rglist", "Pairs", function(x, use.names=TRUE, use.mcols=FALSE) { 20 | stopifnot(isTRUEorFALSE(use.mcols)) 21 | rl <- zipup(ranges(first(x)), ranges(second(x))) 22 | if (!use.mcols) { 23 | mcols(rl) <- NULL 24 | } 25 | rl 26 | }) 27 | 28 | -------------------------------------------------------------------------------- /R/reverse-methods.R: -------------------------------------------------------------------------------- 1 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 | ### The "reverse" generic and methods. 3 | ### 4 | 5 | setGeneric("reverse", function(x, ...) standardGeneric("reverse")) 6 | 7 | setMethod("reverse", "character", 8 | function(x, ...) 9 | { 10 | if (length(x) == 0) 11 | return(x) 12 | sapply(strsplit(x, NULL, fixed=TRUE), 13 | function(xx) paste(rev(xx), collapse="")) 14 | } 15 | ) 16 | 17 | ### This method does NOT preserve normality. 18 | .IRanges.reverse <- function(x, ...) 19 | { 20 | if (length(x) == 0L) 21 | return(x) 22 | args <- S4Vectors:::extraArgsAsList(NULL, ...) 23 | argnames <- names(args) 24 | n2p <- match(c("start", "end", "use.names"), argnames) 25 | if (is.na(n2p[1L])) { 26 | start <- min(start(x)) 27 | } else { 28 | start <- args[[n2p[1L]]] 29 | if (!is.numeric(start)) 30 | stop("'start' must be a vector of integers") 31 | if (!is.integer(start)) 32 | start <- as.integer(start) 33 | if (S4Vectors:::anyMissing(start)) 34 | stop("'start' contains NAs") 35 | } 36 | if (is.na(n2p[2L])) { 37 | end <- max(end(x)) 38 | } else { 39 | end <- args[[n2p[2L]]] 40 | if (!is.numeric(end)) 41 | stop("'end' must be a vector of integers") 42 | if (!is.integer(end)) 43 | end <- as.integer(end) 44 | if (S4Vectors:::anyMissing(end)) 45 | stop("'end' contains NAs") 46 | } 47 | if (!is.na(n2p[3L]) && !S4Vectors:::normargUseNames(args[[n2p[3L]]])) 48 | x <- set_IRanges_names(x, NULL) 49 | ## WARNING: -end(x) *must* appear first in this expression if we want 50 | ## the supplied 'start' and 'end' to be recycled properly. 51 | ## Remember that in R, because of the recycling, addition of numeric 52 | ## vectors of different lengths is not associative i.e. in general 53 | ## '(x + y) + z' is not the same as 'x + (y + z)'. For example: 54 | ## (integer(6) + 1:2) + 1:3 and integer(6) + (1:2 + 1:3) 55 | ## are not the same. 56 | x@start[] <- -end(x) + start + end 57 | x 58 | } 59 | 60 | setMethod("reverse", "IRanges", .IRanges.reverse) 61 | 62 | setMethod("reverse", "NormalIRanges", 63 | function(x, ...) 64 | { 65 | ## callNextMethod() temporarily breaks 'x' as a NormalIRanges object 66 | ## because the returned ranges are ordered from right to left. 67 | x <- callNextMethod() 68 | BiocGenerics:::replaceSlots(x, start=rev(start(x)), 69 | width=rev(width(x)), 70 | NAMES=rev(names(x)), 71 | mcols=S4Vectors:::revROWS(mcols(x, use.names=FALSE))) 72 | } 73 | ) 74 | 75 | setMethod("reverse", "Views", 76 | function(x, ...) 77 | { 78 | x@subject <- rev(subject(x)) 79 | x@ranges <- reverse(ranges(x), start=1L, end=length(subject(x))) 80 | x 81 | } 82 | ) 83 | 84 | setMethod("reverse", "MaskCollection", 85 | function(x, ...) 86 | { 87 | start <- 1L 88 | end <- width(x) 89 | x@nir_list <- lapply(nir_list(x), 90 | function(nir) reverse(nir, start=start, end=end) 91 | ) 92 | x 93 | } 94 | ) 95 | 96 | -------------------------------------------------------------------------------- /R/seqapply.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### The stuff in this file should go somewhere else, probably close to 3 | ### splitAsList() (currently defined in S4Vectors/R/split-methods.R) 4 | ### ------------------------------------------------------------------------- 5 | ### 6 | 7 | ## NOT exported. 8 | `splitAsList<-` <- function(x, f, drop = FALSE, ..., value) { 9 | if (!isTRUEorFALSE(drop)) 10 | stop("'drop' must be TRUE or FALSE") 11 | if (NROW(x) != length(f)) 12 | stop("Length of 'f' must equal the length of 'x'") 13 | ind <- splitAsList(seq_len(NROW(x)), f, drop = drop) 14 | if (length(ind) != length(value)) 15 | stop("Length of 'value' must equal the length of a split on 'f'") 16 | replaceROWS(x, unlist(ind, use.names=FALSE), unlist(value, use.names = FALSE)) 17 | } 18 | 19 | setMethod("unsplit", "List", function(value, f, drop = FALSE) { 20 | value_flat <- unlist(value, use.names = FALSE) 21 | if (NROW(value_flat) != length(f)) 22 | stop("Length of 'unlist(value)' must equal length of 'f'") 23 | splitAsList(value_flat, f, drop = drop) <- value 24 | if (!is.null(ROWNAMES(value_flat))) { 25 | nms <- relist(ROWNAMES(value_flat), value) 26 | splitAsList(ROWNAMES(value_flat), f, drop = drop) <- nms 27 | } 28 | value_flat 29 | }) 30 | 31 | setReplaceMethod("split", "Vector", function(x, f, drop = FALSE, ..., value) { 32 | splitAsList(x, f, drop = drop, ...) <- value 33 | x 34 | }) 35 | 36 | -------------------------------------------------------------------------------- /R/slice-methods.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### Slice the bread 3 | ### ------------------------------------------------------------------------- 4 | 5 | 6 | setGeneric("slice", signature="x", 7 | function(x, lower=-Inf, upper=Inf, ...) standardGeneric("slice")) 8 | 9 | setMethod("slice", "Rle", 10 | function(x, lower = -Inf, upper = Inf, 11 | includeLower = TRUE, includeUpper = TRUE, 12 | rangesOnly = FALSE) 13 | { 14 | if (!isSingleNumber(lower)) { 15 | stop("'lower' must be a single number") 16 | } 17 | if (!isSingleNumber(upper)) { 18 | stop("'upper' must be a single number") 19 | } 20 | if (!isTRUEorFALSE(includeLower)) { 21 | stop("'includeLower' must be TRUE or FALSE") 22 | } 23 | if (!isTRUEorFALSE(includeUpper)) { 24 | stop("'includeUpper' must be TRUE or FALSE") 25 | } 26 | if (!isTRUEorFALSE(rangesOnly)) { 27 | stop("'rangesOnly' must be TRUE or FALSE") 28 | } 29 | if (lower == -Inf) { 30 | ranges <- Rle(TRUE, length(x)) 31 | } else if (includeLower) { 32 | ranges <- (x >= lower) 33 | } else { 34 | ranges <- (x > lower) 35 | } 36 | if (upper < Inf) { 37 | if (includeUpper) { 38 | ranges <- ranges & (x <= upper) 39 | } else { 40 | ranges <- ranges & (x < upper) 41 | } 42 | } 43 | if (rangesOnly) { 44 | as(ranges, "IRanges") 45 | } else { 46 | Views(x, ranges) 47 | } 48 | }) 49 | 50 | setMethod("slice", "RleList", 51 | function(x, lower = -Inf, upper = Inf, 52 | includeLower = TRUE, includeUpper = TRUE, 53 | rangesOnly = FALSE) 54 | { 55 | if (!isSingleNumber(lower)) 56 | stop("'lower' must be a single number") 57 | if (!isSingleNumber(upper)) 58 | stop("'upper' must be a single number") 59 | if (!isTRUEorFALSE(includeLower)) 60 | stop("'includeLower' must be TRUE or FALSE") 61 | if (!isTRUEorFALSE(includeUpper)) 62 | stop("'includeUpper' must be TRUE or FALSE") 63 | if (!isTRUEorFALSE(rangesOnly)) 64 | stop("'rangesOnly' must be TRUE or FALSE") 65 | if (lower == -Inf) { 66 | ranges <- 67 | RleList(lapply(elementNROWS(x), 68 | function(len) Rle(TRUE, len)), 69 | compress=FALSE) 70 | } else if (includeLower) { 71 | ranges <- (x >= lower) 72 | } else { 73 | ranges <- (x > lower) 74 | } 75 | if (upper < Inf) { 76 | if (includeUpper) { 77 | ranges <- ranges & (x <= upper) 78 | } else { 79 | ranges <- ranges & (x < upper) 80 | } 81 | } 82 | if (rangesOnly) { 83 | as(ranges, "CompressedIRangesList") 84 | } else { 85 | RleViewsList(rleList = x, 86 | rangesList = as(ranges, "SimpleIRangesList")) 87 | } 88 | }) 89 | 90 | setMethod("slice", "ANY", function(x, lower=-Inf, upper=Inf, ...) { 91 | slice(as(x, "Rle"), lower=lower, upper=upper, ...) 92 | }) 93 | -------------------------------------------------------------------------------- /R/subsetting-utils.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### Subsetting utility functions 3 | ### ------------------------------------------------------------------------- 4 | 5 | 6 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 7 | ### RangesNSBS objects. 8 | ### 9 | 10 | setClass("RangesNSBS", # not exported 11 | contains="NSBS", 12 | representation( 13 | subscript="IRanges" 14 | ) 15 | ) 16 | 17 | ### Construction methods. 18 | ### Supplied arguments are trusted so we don't check them! 19 | 20 | setMethod("NSBS", "IntegerRanges", 21 | function(i, x, exact=TRUE, strict.upper.bound=TRUE, allow.NAs=FALSE) 22 | { 23 | i_len <- length(i) 24 | if (i_len == 0L) { 25 | ## Return a NativeNSBS object of length 0. 26 | i <- NULL 27 | return(callGeneric()) 28 | } 29 | x_NROW <- NROW(x) 30 | if (is(i, "UnstitchedIPos")) { 31 | ## Return a NativeNSBS object. 32 | i <- i@pos 33 | return(callGeneric()) 34 | } 35 | if (is(i, "StitchedIPos")) 36 | i <- i@pos_runs # TODO: Use collapse() (or stitch()?) when 37 | # it's available 38 | i_start <- start(i) 39 | i_end <- end(i) 40 | if (min(i_start) < 1L || strict.upper.bound && max(i_end) > x_NROW) 41 | S4Vectors:::.subscript_error("subscript contains out-of-bounds ", 42 | "ranges") 43 | if (i_len > 1L) { 44 | ans <- new2("RangesNSBS", subscript=i, 45 | upper_bound=x_NROW, 46 | upper_bound_is_strict=strict.upper.bound, 47 | check=FALSE) 48 | return(ans) 49 | } 50 | if (i_end > i_start) { 51 | ans <- new2("RangeNSBS", subscript=c(i_start, i_end), 52 | upper_bound=x_NROW, 53 | upper_bound_is_strict=strict.upper.bound, 54 | check=FALSE) 55 | return(ans) 56 | } 57 | ## Return a NativeNSBS object of length <= 1. 58 | if (i_end == i_start) { 59 | i <- i_start 60 | } else { 61 | i <- NULL 62 | } 63 | callGeneric() 64 | } 65 | ) 66 | 67 | ### Other methods. 68 | 69 | setMethod("as.integer", "RangesNSBS", 70 | function(x) unlist_as_integer(x@subscript) 71 | ) 72 | 73 | setMethod("length", "RangesNSBS", function(x) sum(width(x@subscript))) 74 | 75 | setMethod("anyDuplicated", "RangesNSBS", 76 | function(x, incomparables=FALSE, ...) !isDisjoint(x@subscript) 77 | ) 78 | 79 | setMethod("isStrictlySorted", "RangesNSBS", function(x) isNormal(x@subscript)) 80 | 81 | 82 | ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 83 | ### "extractROWS" methods for subsetting *by* an IntegerRanges object. 84 | ### 85 | 86 | setMethod("extractROWS", c("vector_OR_factor", "RangesNSBS"), 87 | function(x, i) 88 | { 89 | start <- start(i@subscript) 90 | width <- width(i@subscript) 91 | S4Vectors:::extract_ranges_from_vector_OR_factor(x, start, width) 92 | } 93 | ) 94 | 95 | setMethod("extractROWS", c("array", "RangesNSBS"), 96 | S4Vectors:::default_extractROWS 97 | ) 98 | setMethod("extractROWS", c("data.frame", "RangesNSBS"), 99 | S4Vectors:::default_extractROWS 100 | ) 101 | 102 | setMethod("extractROWS", c("Rle", "RangesNSBS"), 103 | function(x, i) 104 | { 105 | start <- start(i@subscript) 106 | width <- width(i@subscript) 107 | ans <- S4Vectors:::extract_ranges_from_Rle(x, start, width) 108 | mcols(ans) <- extractROWS(mcols(x, use.names=FALSE), i) 109 | ans 110 | } 111 | ) 112 | 113 | -------------------------------------------------------------------------------- /R/tile-methods.R: -------------------------------------------------------------------------------- 1 | ### ========================================================================= 2 | ### "tile" methods 3 | ### ------------------------------------------------------------------------- 4 | ### 5 | 6 | ### TODO: We have a profileration of tools for creating these "sliding 7 | ### windows" or "tiles": successiveIRanges(), tileGenome(), tile(), and now 8 | ### slidingWindows(). With no visible coherent naming scheme. Introducing 9 | ### a new verb each time we get frustrated because the existing tools don't 10 | ### let us create tiles or windows exactly the way we'd like for the use case 11 | ### of the day is not a sustainable strategy in the long run. This just adds 12 | ### more and more confusion for the end user. 13 | ### So some effort will need to be done towards unification of all these 14 | ### tools. H.P. -- Oct 16, 2016. 15 | 16 | setGeneric("tile", function(x, n, width, ...) standardGeneric("tile"), 17 | signature="x") 18 | 19 | setMethod("tile", "IntegerRanges", function(x, n, width, ...) { 20 | if (!missing(n)) { 21 | if (!missing(width)) 22 | stop("only one of 'n' or 'width' can be specified") 23 | if (any(IRanges::width(x) < n)) 24 | stop("some width(x) are less than 'n'") 25 | if (any(n < 0L)) 26 | stop("some 'n' are negative") 27 | n <- S4Vectors:::recycleVector(n, length(x)) 28 | } 29 | if (!missing(width)) { 30 | if (!missing(n)) 31 | stop("only one of 'n' or 'width' can be specified") 32 | if (any(width < 0L)) 33 | stop("some 'width' are negative") 34 | n <- ceiling(width(x) / width) 35 | } 36 | width <- IRanges::width(x) / n 37 | ## The floor() is intentional for compatibility with Jim Kent's BigWig code 38 | ## tileGenome() uses ceiling() instead 39 | tile.end <- floor(unlist_as_integer(IRanges(rep(1L, length(n)), width=n)) * 40 | rep(width, n)) 41 | tile.end.abs <- tile.end + rep(start(x), n) - 1L 42 | tile.width <- S4Vectors:::diffWithInitialZero(as.integer(tile.end.abs)) 43 | p <- PartitioningByWidth(n, names = names(x)) 44 | tile.width[start(p)] <- tile.end[start(p)] 45 | relist(IRanges(width=tile.width, end=tile.end.abs), p) 46 | }) 47 | 48 | ### ========================================================================= 49 | ### "slidingWindows" methods 50 | ### ------------------------------------------------------------------------- 51 | ### 52 | 53 | setGeneric("slidingWindows", 54 | function(x, width, step = 1L, ...) standardGeneric("slidingWindows"), 55 | signature="x") 56 | 57 | setMethod("slidingWindows", "IntegerRanges", function(x, width, step = 1L) { 58 | if (!isSingleNumber(width)) 59 | stop("'width' must be a single, non-NA number") 60 | if (!isSingleNumber(step)) 61 | stop("'step' must be a single, non-NA number") 62 | if (any(width < 0L)) 63 | stop("some 'width' are negative") 64 | if (any(step < 0L)) 65 | stop("some 'step' are negative") 66 | n <- ceiling(pmax(width(x) - width, 0L) / step) + 1L 67 | window.starts <- unlist_as_integer(IRanges(rep(0L, length(n)), width=n)) * 68 | step + 1L 69 | windows <- restrict(IRanges(window.starts, width=width), 70 | end=rep(width(x), n)) 71 | windows.abs <- shift(windows, rep(start(x), n) - 1L) 72 | relist(windows.abs, PartitioningByWidth(n, names = names(x))) 73 | }) 74 | -------------------------------------------------------------------------------- /R/zzz.R: -------------------------------------------------------------------------------- 1 | ### 2 | 3 | .onUnload <- function(libpath) 4 | { 5 | library.dynam.unload("IRanges", libpath) 6 | } 7 | 8 | .test <- function() BiocGenerics:::testPackage("IRanges") 9 | 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [](https://bioconductor.org/packages/IRanges) 2 | 3 | [](https://bioconductor.org/) 4 | 5 | **IRanges** is an R/Bioconductor package that provides the foundation of integer range manipulation in Bioconductor. 6 | 7 | See https://bioconductor.org/packages/IRanges for more information including how to install the release version of the package (please refrain from installing directly from GitHub). 8 | 9 | _IRanges sticker courtesy of [Roberto Bonelli](https://github.com/Robbie90)._ 10 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | Immediate TODO list 2 | ------------------- 3 | 4 | - Bug fix: Combining RangedData objects is currently broken (IRanges 1.9.20): 5 | library(IRanges) 6 | ranges <- IRanges(c(1,2,3),c(4,5,6)) 7 | rd1 <- RangedData(ranges) 8 | rd2 <- RangedData(shift(ranges, 100)) 9 | rd <- c(rd1, rd2) # Seems to work (with some warnings)... 10 | validObject(rd) # but returns an invalid object! 11 | 12 | - Herve: Make the MaskCollection class a derivative of the SimpleIRangesList 13 | class. 14 | 15 | - Herve: Use a different name for "reverse" method for IRanges and 16 | MaskCollection objects. Seems like, for IRanges objects, reverse() 17 | and reflect() are doing the same thing, so I should just keep (and 18 | eventually adapt) the latter. Also, I should add a "reflect" 19 | method for SimpleIRangesList objects that would do what the current 20 | "reverse" method for MaskCollection objects does. 21 | Once this is done, adapt R/reverse.R file in Biostrings to use reflect() 22 | instead of reverse() wherever needed. 23 | 24 | - Clean up endomorphisms. 25 | 26 | 27 | Long term TODO list 28 | ------------------- 29 | 30 | o RangesList: 31 | - parallel rbind 32 | - binary ops: "nearest", "intersect", "setdiff", "union" 33 | - 'y' omitted: become n-ary ops on items in collection 34 | - 'y' specified: performed element-wise 35 | - unary ops: "coverage" etc are vectorized 36 | 37 | o DataTable: 38 | - group generics (Math, Ops, Summary) 39 | 40 | o SplitDataFrameList: 41 | - rbind 42 | 43 | o IO: 44 | - xscan() - read data directly into XVector objects 45 | 46 | 47 | ------------------------------------- 48 | Conceptual framework (by Michael) 49 | ------------------------------------- 50 | 51 | Basic problem: We have lots of (long) data series and need a way to 52 | efficiently represent and manipulate them. 53 | 54 | A series is a vector, except that the positions of the elements are 55 | meaningful. That is, we often expect strong auto-correlation. We have 56 | an abstraction called "Vector" for representing these series. 57 | 58 | There are currently two optimized means of storing long series: 59 | 60 | 1) Externally, currently only in memory, in XVector derivatives. 61 | The main benefit here is avoiding unnecessary copying, though there 62 | is potential for vectors stored in databases and flat files on disk 63 | (but this is outside our use case). 64 | 65 | 2) Run-length encoding (Rle class). This is a classic means of 66 | compressing discrete-valued series. It is very efficient, as long as 67 | there are long runs of equal value. 68 | 69 | Rle, so far, is far ahead of XVector in terms of direct 70 | usefulness. If XVector were implemented with an environment, rather 71 | than an external pointer, adding functionality would be easier. Could 72 | carry some things over from externalVector. 73 | 74 | As the sequence of observations in a series is important, we often 75 | want to manipulate specific regions of the series. We can use the 76 | window() function to select a particular region from a Vector, and a 77 | logical Rle can represent a selection of multiple regions. A slightly 78 | more general representation, that supports overlapping regions, is the 79 | IntegerRanges class. 80 | 81 | An IntegerRanges object holds any number of start,width pairs that describe 82 | closed intervals representing the set of integers that fall within the 83 | endpoints. The primary implementation is IRanges, which stores the 84 | information as two integer vectors. 85 | 86 | Often the endpoints of the intervals are interesting independent of 87 | the underlying sequence. Many utilities are implemented for 88 | manipulating and analyzing IntegerRanges. These include: 89 | 90 | 1) overlap detection 91 | 2) nearest neighbors: precede, follow, nearest 92 | 3) set operations: (p)union, (p)intersect, (p)setdiff, gaps 93 | 4) coverage, too bio specific? rename to 'table'? 94 | 5) resolving overlap: reduce and (soon) collapse 95 | 6) transformations: flank, reflect, restrict, narrow... 96 | 7) (soon) mapping/alignment 97 | 98 | There are two ways to explicitly pair an IntegerRanges object with a 99 | Vector: 100 | 101 | 1) Masking, as in MaskedXString, where only the elements outside of 102 | the IntegerRanges are considered by an operation. 103 | 104 | 2) Views, which are essentially lists of subsequences. This 105 | relies in the fly-weight pattern for efficiency. Several fast paths, 106 | like viewSums and viewMaxs, are implemented. There is an RleViews 107 | and an XIntegerViews (is this one currently used at all?). 108 | 109 | Views are limited to subsequences derived from a single sequence. For 110 | more general lists of sequences, we have a separate framework, based 111 | on the List class. The List optionally ensures that all of its elements 112 | are derived from a specified type, and it also aims to efficiently 113 | represent a major use case of lists: splitting a vector by a factor. 114 | The indices of the elements with each factor level are stored, but 115 | there is no physical split of the vector into separate list elements. 116 | 117 | A special case that often occurs in data analysis is a list containing 118 | a set of variables in the same dataset. This problem is solved by 119 | 'data.frame' in base R, and we have an equivalent DataFrame class 120 | that can hold any type of R object, as long as it has a vector semantic. 121 | 122 | Many of the important data structures have List analogs. These 123 | include all atomic types, as well as: 124 | 125 | * SplitDataFrameList: a list of DataFrames that have the same 126 | columns (usually the result of a split) 127 | 128 | * RangesList: Essentially just a list of IntegerRanges objects, but often 129 | used for splitting IntegerRanges by their "space" (e.g. chromosome) 130 | 131 | -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | citEntry(entry="article", 2 | title = "Software for Computing and Annotating Genomic Ranges", 3 | author = personList( as.person("Michael Lawrence" ), 4 | as.person("Wolfgang Huber" ), 5 | as.person("Herv\\'e Pag\\`es" ), 6 | as.person("Patrick Aboyoun" ), 7 | as.person("Marc Carlson" ), 8 | as.person("Robert Gentleman" ), 9 | as.person("Martin Morgan" ), 10 | as.person("Vincent Carey" )), 11 | year = 2013, 12 | journal = "{PLoS} Computational Biology", 13 | volume = "9", 14 | issue = "8", 15 | doi = "10.1371/journal.pcbi.1003118", 16 | url = "http://www.ploscompbiol.org/article/info%3Adoi%2F10.1371%2Fjournal.pcbi.1003118", 17 | textVersion = 18 | "Lawrence M, Huber W, Pag\\`es H, Aboyoun P, Carlson M, et al. (2013) Software for Computing and Annotating Genomic Ranges. PLoS Comput Biol 9(8): e1003118. doi:10.1371/journal.pcbi.1003118" ) 19 | -------------------------------------------------------------------------------- /inst/extdata/ce2chrM.bed: -------------------------------------------------------------------------------- 1 | chrM 13357 13651 trf 2 162.5 2 67 19 173 47 0 0 52 1.00 TA 2 | chrM 13436 13585 trf 7 23.9 7 66 28 61 46 0 0 53 1.00 ATTATAA 3 | chrM 13406 13658 trf 9 28.7 9 66 15 63 45 0 0 54 0.99 TATTATATT 4 | -------------------------------------------------------------------------------- /inst/extdata/ce2chrM.fa.out: -------------------------------------------------------------------------------- 1 | SW perc perc perc query position in query matching repeat position in repeat 2 | score div. del. ins. sequence begin end (left) repeat class/family begin end (left) ID 3 | 4 | 210 19.5 0.0 7.2 chrM 433 515 (13279) + T-rich Low_complexity 2 78 (0) 1 5 | 28 6.1 0.0 0.0 chrM 543 591 (13203) + AT_rich Low_complexity 1 49 (0) 2 6 | 34 2.4 0.0 0.0 chrM 1345 1385 (12409) + AT_rich Low_complexity 1 41 (0) 3 7 | 26 8.2 0.0 0.0 chrM 2464 2524 (11270) + AT_rich Low_complexity 1 61 (0) 4 8 | 239 21.5 0.8 9.7 chrM 2566 2699 (11095) + T-rich Low_complexity 3 124 (0) 5 9 | 27 7.3 0.0 0.0 chrM 3922 3976 (9818) + AT_rich Low_complexity 1 55 (0) 6 10 | 37 5.7 0.0 3.3 chrM 4206 4296 (9498) + AT_rich Low_complexity 1 88 (0) 7 11 | 22 5.6 0.0 0.0 chrM 4759 4794 (9000) + AT_rich Low_complexity 1 36 (0) 8 12 | 28 2.9 0.0 0.0 chrM 5437 5471 (8323) + AT_rich Low_complexity 1 35 (0) 9 13 | 228 18.5 1.9 0.0 chrM 5538 5591 (8203) + T-rich Low_complexity 5 59 (0) 10 14 | 22 0.0 0.0 0.0 chrM 6584 6605 (7189) + AT_rich Low_complexity 1 22 (0) 11 15 | 36 9.7 0.0 0.0 chrM 6699 6811 (6983) + AT_rich Low_complexity 1 113 (0) 12 16 | 21 8.9 0.0 0.0 chrM 6978 7033 (6761) + AT_rich Low_complexity 1 56 (0) 13 17 | 26 8.8 0.0 0.0 chrM 7521 7588 (6206) + AT_rich Low_complexity 1 68 (0) 14 18 | 30 8.3 0.0 0.0 chrM 7794 7865 (5929) + AT_rich Low_complexity 1 72 (0) 15 19 | 21 0.0 0.0 0.0 chrM 8054 8074 (5720) + AT_rich Low_complexity 1 21 (0) 16 20 | 39 5.0 0.0 0.0 chrM 10561 10620 (3174) + AT_rich Low_complexity 1 60 (0) 17 21 | 207 16.8 6.6 4.7 chrM 10656 10761 (3033) + (TTTAA)n Simple_repeat 1 108 (0) 18 22 | 32 2.6 0.0 0.0 chrM 10947 10985 (2809) + AT_rich Low_complexity 1 39 (0) 19 23 | 25 0.0 0.0 0.0 chrM 11805 11829 (1965) + AT_rich Low_complexity 1 25 (0) 20 24 | 21 3.6 0.0 0.0 chrM 12027 12054 (1740) + AT_rich Low_complexity 1 28 (0) 21 25 | 24 3.2 0.0 0.0 chrM 12320 12350 (1444) + AT_rich Low_complexity 1 31 (0) 22 26 | 27 8.1 0.0 0.0 chrM 12727 12788 (1006) + AT_rich Low_complexity 1 62 (0) 23 27 | 22 9.9 0.0 0.0 chrM 12883 12953 (841) + AT_rich Low_complexity 1 71 (0) 24 28 | 60 7.2 0.0 1.9 chrM 13006 13161 (633) + AT_rich Low_complexity 1 153 (0) 25 29 | 28 9.1 0.0 0.0 chrM 13193 13269 (525) + AT_rich Low_complexity 1 77 (0) 26 30 | 468 6.9 9.4 0.0 chrM 13358 13516 (278) + (TA)n Simple_repeat 1 174 (0) 27 31 | 344 8.5 8.3 2.4 chrM 13491 13658 (136) + (TTATA)n Simple_repeat 2 179 (0) 28 32 | -------------------------------------------------------------------------------- /inst/include/IRanges_defines.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | IRanges C interface: typedefs and defines 3 | ----------------------------------------- 4 | 5 | The IRanges C interface is split in 2 files: 6 | 1. IRanges_defines.h (this file): contains the typedefs and defines 7 | of the interface. 8 | 2. IRanges_interface.h (in this directory): contains the prototypes 9 | of the IRanges C routines that are part of the interface. 10 | 11 | Please consult IRanges_interface.h for how to use this interface in your 12 | package. 13 | 14 | *****************************************************************************/ 15 | #ifndef IRANGES_DEFINES_H 16 | #define IRANGES_DEFINES_H 17 | 18 | #include "S4Vectors_defines.h" 19 | 20 | #include 21 | #include 22 | 23 | 24 | /* 25 | * *_holder structs. 26 | */ 27 | 28 | typedef struct compressed_chars_list_holder { 29 | int length; 30 | const char *unlisted; 31 | const int *breakpoints; 32 | } CompressedCharsList_holder; 33 | 34 | typedef struct compressed_ints_list_holder { 35 | int length; 36 | const int *unlisted; 37 | const int *breakpoints; 38 | } CompressedIntsList_holder; 39 | 40 | typedef struct compressed_doubles_list_holder { 41 | int length; 42 | const double *unlisted; 43 | const int *breakpoints; 44 | } CompressedDoublesList_holder; 45 | 46 | typedef struct iranges_holder { 47 | const char *classname; 48 | int is_constant_width; 49 | int length; 50 | const int *width; 51 | const int *start; 52 | const int *end; 53 | int SEXP_offset; /* offset in 'names' member below */ 54 | SEXP names; 55 | } IRanges_holder; 56 | 57 | typedef struct compressed_iranges_list_holder { 58 | const char *classname; 59 | int length; 60 | const int *end; 61 | IRanges_holder unlistData_holder; 62 | } CompressedIRangesList_holder; 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /inst/include/IRanges_interface.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | IRanges C interface: prototypes 3 | ------------------------------- 4 | 5 | The IRanges C interface is split in 2 files: 6 | 1. IRanges_defines.h (in this directory): contains the typedefs and 7 | defines of the interface. 8 | 2. IRanges_interface.h (this file): contains the prototypes of the 9 | IRanges C routines that are part of the interface. 10 | 11 | *****************************************************************************/ 12 | #include "IRanges_defines.h" 13 | 14 | 15 | /* 16 | * Comparing integer ranges. 17 | * (see IPosRanges_comparison.c) 18 | */ 19 | 20 | int overlap_code( 21 | int x_start, 22 | int x_width, 23 | int y_start, 24 | int y_width 25 | ); 26 | 27 | int invert_overlap_code(int code); 28 | 29 | /* 30 | * Low-level manipulation of IRanges objects. 31 | * (see IRanges_class.c) 32 | */ 33 | 34 | SEXP get_IRanges_start(SEXP x); 35 | 36 | SEXP get_IRanges_width(SEXP x); 37 | 38 | SEXP get_IRanges_names(SEXP x); 39 | 40 | int get_IRanges_length(SEXP x); 41 | 42 | IRanges_holder hold_IRanges(SEXP x); 43 | 44 | int get_length_from_IRanges_holder(const IRanges_holder *x_holder); 45 | 46 | int get_width_elt_from_IRanges_holder(const IRanges_holder *x_holder, int i); 47 | 48 | int get_start_elt_from_IRanges_holder(const IRanges_holder *x_holder, int i); 49 | 50 | int get_end_elt_from_IRanges_holder(const IRanges_holder *x_holder, int i); 51 | 52 | SEXP get_names_elt_from_IRanges_holder(const IRanges_holder *x_holder, int i); 53 | 54 | IRanges_holder get_linear_subset_from_IRanges_holder(const IRanges_holder *x_holder, int offset, int length); 55 | 56 | void set_IRanges_names(SEXP x, SEXP names); 57 | 58 | void copy_IRanges_slots(SEXP x, SEXP x0); 59 | 60 | SEXP new_IRanges(const char *classname, SEXP start, SEXP width, SEXP names); 61 | 62 | SEXP new_IRanges_from_IntPairAE(const char *classname, const IntPairAE *intpair_ae); 63 | 64 | SEXP new_list_of_IRanges_from_IntPairAEAE(const char *element_type, const IntPairAEAE *intpair_aeae); 65 | 66 | SEXP alloc_IRanges(const char *classname, int length); 67 | 68 | /* 69 | * Low-level manipulation of Grouping objects. 70 | * (see Grouping_class.c) 71 | */ 72 | 73 | SEXP get_H2LGrouping_high2low(SEXP x); 74 | 75 | SEXP get_H2LGrouping_low2high(SEXP x); 76 | 77 | SEXP get_Partitioning_names(SEXP x); 78 | 79 | SEXP get_PartitioningByEnd_end(SEXP x); 80 | 81 | SEXP new_PartitioningByEnd(const char *classname, SEXP end, SEXP names); 82 | 83 | /* 84 | * Low-level manipulation of CompressedList objects. 85 | * (see CompressedList_class.c) 86 | */ 87 | 88 | SEXP get_CompressedList_unlistData(SEXP x); 89 | 90 | SEXP get_CompressedList_partitioning(SEXP x); 91 | 92 | int get_CompressedList_length(SEXP x); 93 | 94 | SEXP get_CompressedList_names(SEXP x); 95 | 96 | SEXP new_CompressedList(const char *classname, SEXP unlistData, SEXP partitioning); 97 | 98 | CompressedIntsList_holder hold_CompressedIntegerList(SEXP x); 99 | 100 | int get_length_from_CompressedIntsList_holder(const CompressedIntsList_holder *x_holder); 101 | 102 | Ints_holder get_elt_from_CompressedIntsList_holder(const CompressedIntsList_holder *x_holder, int i); 103 | 104 | /* 105 | * Low-level manipulation of CompressedIRangesList objects. 106 | * (see CompressedIRangesList_class.c) 107 | */ 108 | 109 | CompressedIRangesList_holder hold_CompressedIRangesList(SEXP x); 110 | 111 | int get_length_from_CompressedIRangesList_holder(const CompressedIRangesList_holder *x_holder); 112 | 113 | IRanges_holder get_elt_from_CompressedIRangesList_holder(const CompressedIRangesList_holder *x_holder, int i); 114 | 115 | int get_eltNROWS_from_CompressedIRangesList_holder(const CompressedIRangesList_holder *x_holder, int i); 116 | 117 | -------------------------------------------------------------------------------- /inst/unitTests/test_AtomicList-class.R: -------------------------------------------------------------------------------- 1 | test_AtomicList_constructors <- function() { 2 | subclasses <- c(logical="LogicalList", 3 | integer="IntegerList", 4 | #double="NumericList", 5 | numeric="NumericList", 6 | complex="ComplexList", 7 | character="CharacterList", 8 | raw="RawList", 9 | Rle="RleList") 10 | for (elt_type in names(subclasses)) { 11 | subclass <- subclasses[[elt_type]] 12 | constructor <- get(subclass) 13 | vec1 <- get(elt_type)(6) 14 | vec2 <- get(elt_type)(8) 15 | target <- list(A=vec1, B=vec2) 16 | for (compress in c(TRUE, FALSE)) { 17 | current <- constructor(A=vec1, B=vec2, compress=compress) 18 | checkTrue(is(current, subclass)) 19 | checkIdentical(compress, is(current, "CompressedList")) 20 | checkIdentical(elt_type, elementType(current)) 21 | checkIdentical(target, as.list(current)) 22 | checkIdentical(unname(target), as.list(current, use.names=FALSE)) 23 | } 24 | } 25 | } 26 | 27 | test_AtomicList_general <- function() { 28 | vec1 <- c(1L,2L,NA,3L,NA,5L,2L,8L) 29 | vec2 <- c(NA,15L,45L,20L,NA,1L,15L,100L,80L,5L,NA) 30 | for (compress in c(TRUE, FALSE)) { 31 | for (type in c("IntegerList", "RleList")) { 32 | list1 <- do.call(type, list(one = vec1, vec2, compress = compress)) 33 | checkIdentical(as.list(list1 %in% c(1L, 5L)), 34 | lapply(list1, "%in%", c(1L, 5L))) 35 | checkIdentical(lapply(list1 %in% 36 | IntegerList(one = vec1, vec2, 37 | compress = compress), 38 | as.vector), 39 | mapply("%in%", lapply(list1, as.vector), 40 | list(one = vec1, vec2))) 41 | checkIdentical(as.list(is.na(list1)), lapply(list1, is.na)) 42 | checkIdentical(as.list(match(list1, c(1L, 5L))), 43 | lapply(list1, match, c(1L, 5L))) 44 | checkIdentical(lapply(match(list1, 45 | IntegerList(one = vec1, vec2, 46 | compress = compress)), 47 | as.vector), 48 | mapply(match, lapply(list1, as.vector), 49 | list(one = vec1, vec2))) 50 | checkIdentical(as.list(sort(list1)), lapply(list1, sort)) 51 | checkIdentical(as.list(unique(list1)), lapply(list1, unique)) 52 | } 53 | } 54 | } 55 | 56 | test_RleList_methods <- function() { 57 | x1 <- RleList(11:15, 15L, integer(0), 15:16, compress=FALSE) 58 | x2 <- RleList(11:15, 15L, integer(0), 15:16, compress=TRUE) 59 | checkIdentical(as(runValue(x1), "CompressedIntegerList"), runValue(x2)) 60 | checkIdentical(as(runLength(x1), "CompressedIntegerList"), runLength(x2)) 61 | checkIdentical(as(ranges(x1), "CompressedIRangesList"), ranges(x2)) 62 | 63 | a1 <- Rle(1, 999722111) 64 | a2 <- 20 * a1 65 | a <- RleList(a1, a2, compress=TRUE) 66 | b1 <- c(a1, a1) 67 | b2 <- 20 * b1 68 | b <- RleList(b1, b2, compress=FALSE) 69 | ## FIXME: 'a1 <= 19:21' is taking forever and eats up all the memory in 70 | ## BioC <= 2.12! Seems like 'a1' is expanded to integer vector first, which 71 | ## is not good :-/ 72 | #for (y in list(8L, 8, 19:21)) { 73 | for (y in list(8L, 8)) { 74 | ## With a CompressedRleList 75 | target <- RleList(a1 <= y, a2 <= y, compress=TRUE) 76 | current <- a <= y 77 | checkIdentical(target, current) 78 | ## With a SimpleRleList 79 | target <- RleList(b1 <= y, b2 <= y, compress=FALSE) 80 | current <- b <= y 81 | checkIdentical(target, current) 82 | } 83 | } 84 | 85 | -------------------------------------------------------------------------------- /inst/unitTests/test_DataFrame-utils.R: -------------------------------------------------------------------------------- 1 | 2 | ## splitting 3 | test_DataFrame_splitting <- function() { 4 | data(swiss) 5 | rn <- rownames(swiss) 6 | sw <- DataFrame(swiss, row.names=rn) 7 | swisssplit <- split(swiss, swiss$Education) 8 | 9 | ## split 10 | swsplit <- split(sw, sw[["Education"]]) 11 | checkTrue(validObject(swsplit)) 12 | checkIdentical(as.list(lapply(swsplit, as.data.frame)), swisssplit) 13 | checkTrue(validObject(split(DataFrame(IRanges(1:26, 1:26), LETTERS), 14 | letters))) 15 | } 16 | 17 | -------------------------------------------------------------------------------- /inst/unitTests/test_HitsList.R: -------------------------------------------------------------------------------- 1 | test_HitsList_as_matrix <- function() { 2 | x <- IRangesList(chr1=IRanges(1, 5), chr2=IRanges(6, 10)) 3 | y <- IRangesList(chr2=IRanges(8, 10)) 4 | checkIdentical(as.matrix(findOverlaps(x, y)), 5 | cbind(queryHits = 2L, subjectHits = 1L)) 6 | } 7 | -------------------------------------------------------------------------------- /inst/unitTests/test_IRanges-class.R: -------------------------------------------------------------------------------- 1 | test_IRanges_names <- function() { 2 | range1 <- IRanges(start=c(1,2,3), end=c(5,2,8)) 3 | 4 | checkIdentical(names(range1), NULL) 5 | nms <- c("a", NA, "b") 6 | names(range1) <- nms 7 | checkIdentical(names(range1), nms) 8 | checkTrue(validObject(nms)) 9 | names(range1) <- NULL 10 | checkTrue(validObject(nms)) 11 | checkIdentical(names(range1), NULL) 12 | names(range1) <- "a" 13 | checkTrue(validObject(range1)) 14 | checkIdentical(names(range1), c("a", NA, NA)) 15 | 16 | checkException(names(range1) <- c("a", "b", "c", "d"), silent = TRUE) 17 | } 18 | 19 | test_IntegerRanges_isDisjoint <- function() { 20 | ir1 <- IRanges(c(2,5,1), c(3,7,3)) 21 | ir2 <- IRanges(c(2,9,5), c(3,9,6)) 22 | ir3 <- IRanges(1, 5) 23 | checkIdentical(isDisjoint(ir1), FALSE) 24 | checkIdentical(isDisjoint(ir2), TRUE) 25 | checkIdentical(isDisjoint(ir3), TRUE) 26 | 27 | ## Handling of zero-width ranges 28 | current <- sapply(11:17, 29 | function(i) 30 | isDisjoint(IRanges(c(12, i), width=c(4, 0)))) 31 | target <- rep(c(TRUE, FALSE, TRUE), c(2, 3, 2)) 32 | checkIdentical(target, current) 33 | } 34 | 35 | test_IRanges_concatenate <- function() { 36 | range <- IRanges(start=c(1,2,3,1), end=c(5,2,8,3)) 37 | srange <- split(range, start(range) == 1) 38 | checkIdentical(srange, IRangesList(`FALSE` = range[2:3], `TRUE` = range[c(1,4)])) 39 | checkIdentical(do.call(c, unname(as.list(srange))), 40 | IRanges(c(2,3,1,1), c(2,8,5,3))) 41 | 42 | ir1 <- IRanges(1, 10) 43 | ir2 <- IRanges(c(1, 15), width=5) 44 | mcols(ir2) <- DataFrame(score=1:2) 45 | checkIdentical(mcols(c(ir1, ir2)), 46 | DataFrame(score = c(NA, 1L, 2L))) 47 | 48 | ## Concatenating multiple IRanges object with varying mcols 49 | mcols(ir1) <- DataFrame(gc=0.78) 50 | ir12 <- c(ir1, ir2, ignore.mcols=TRUE) 51 | checkIdentical(mcols(ir12), NULL) 52 | target_mcols <- DataFrame(gc=c(0.78, NA, NA), score=c(NA, 1:2)) 53 | mcols(ir12) <- target_mcols 54 | checkIdentical(c(ir1, ir2), ir12) 55 | } 56 | 57 | test_IRanges_annotation <- function() { 58 | range <- IRanges(c(1, 4), c(5, 7)) 59 | mcols(range) <- DataFrame(a = 1:2) 60 | checkIdentical(mcols(range)[,1], 1:2) 61 | checkIdentical(mcols(range[2:1])[,1], 2:1) 62 | checkIdentical(mcols(c(range,range))[,1], rep(1:2,2)) 63 | } 64 | 65 | -------------------------------------------------------------------------------- /inst/unitTests/test_IRanges-constructor.R: -------------------------------------------------------------------------------- 1 | test_IRanges_constructor <- function() { 2 | ir0 <- IRanges() 3 | checkTrue(is(ir0, "IRanges")) 4 | checkTrue(validObject(ir0)) 5 | checkIdentical(0L, length(ir0)) 6 | 7 | ir1 <- IRanges(start=4:-2, end=13:7) 8 | checkTrue(is(ir1, "IRanges")) 9 | checkTrue(validObject(ir1)) 10 | checkIdentical(7L, length(ir1)) 11 | 12 | ir2 <- IRanges(start=4:-2, width=10) 13 | checkIdentical(ir1, ir2) 14 | 15 | ir3 <- IRanges(end=13:7, width=10) 16 | checkIdentical(ir1, ir3) 17 | 18 | ir <- IRanges(start=c(a=1, b=2, c=3), end=c(d=10)) 19 | checkTrue(is(ir, "IRanges")) 20 | checkTrue(validObject(ir)) 21 | checkIdentical(3L, length(ir)) 22 | 23 | ir <- IRanges(matrix(1:24), 30) 24 | checkTrue(is(ir, "IRanges")) 25 | checkTrue(validObject(ir)) 26 | checkIdentical(24L, length(ir)) 27 | 28 | ir <- IRanges(array(1:24, 4:2), 30) 29 | checkTrue(is(ir, "IRanges")) 30 | checkTrue(validObject(ir)) 31 | checkIdentical(24L, length(ir)) 32 | 33 | ## Solve NAs in 'start', 'end', or 'width'. 34 | ir <- IRanges(start=c(NA, -2, 15, -119), 35 | end =c(26, NA, 34, -100), 36 | width=c(20, 20, NA, 20)) 37 | checkTrue(is(ir, "IRanges")) 38 | checkTrue(validObject(ir)) 39 | checkIdentical(4L, length(ir)) 40 | checkIdentical(c( 7L, -2L, 15L, -119L), start(ir)) 41 | checkIdentical(c(26L, 17L, 34L, -100L), end(ir)) 42 | checkIdentical(c(20L, 20L, 20L, 20L), width(ir)) 43 | } 44 | 45 | -------------------------------------------------------------------------------- /inst/unitTests/test_IRangesList-class.R: -------------------------------------------------------------------------------- 1 | test_IRangesList_construction <- function() { 2 | range1 <- IRanges(start=c(1,2,3), end=c(5,2,8)) 3 | range2 <- IRanges(start=c(15,45,20,1), end=c(15,100,80,5)) 4 | for (compress in c(TRUE, FALSE)) { 5 | empty <- IRangesList(compress=compress) 6 | checkTrue(validObject(empty)) 7 | checkIdentical(length(empty), 0L) 8 | named <- IRangesList(one = range1, two = range2, compress=compress) 9 | checkTrue(validObject(named)) 10 | checkIdentical(length(named), 2L) 11 | checkIdentical(start(named), 12 | IntegerList(one = start(range1), two = start(range2), 13 | compress=compress)) 14 | checkIdentical(end(named), 15 | IntegerList(one = end(range1), two = end(range2), 16 | compress=compress)) 17 | checkIdentical(width(named), 18 | IntegerList(one = width(range1), two = width(range2), 19 | compress=compress)) 20 | checkIdentical(names(named), c("one", "two")) 21 | checkIdentical(range1, named[[1]]) 22 | unnamed <- IRangesList(range1, range2, compress=compress) 23 | checkTrue(validObject(unnamed)) 24 | checkIdentical(length(unnamed), 2L) 25 | checkIdentical(range2, unnamed[[2]]) 26 | checkIdentical(names(unnamed), NULL) 27 | } 28 | } 29 | 30 | test_IRangesList_subset <- function() { 31 | for (compress in c(TRUE, FALSE)) { 32 | range1 <- IRanges(start=c(1,2,3), end=c(5,2,8)) 33 | range2 <- IRanges(start=c(1,15,20,45), end=c(5,15,100,80)) 34 | collection <- IRangesList(one = range1, range2, compress=compress) 35 | checkIdentical(subsetByOverlaps(collection, IRangesList()), 36 | IRangesList(one=IRanges(), IRanges(), compress=compress)) 37 | checkIdentical( 38 | subsetByOverlaps(collection, 39 | IRangesList(IRanges(4, 6), IRanges(50, 70), 40 | compress=compress)), 41 | IRangesList(one=IRanges(c(1,3),c(5,8)), 42 | IRanges(c(20,45),c(100,80)), 43 | compress=compress)) 44 | checkIdentical( 45 | subsetByOverlaps(collection, 46 | IRangesList(IRanges(50, 70), one=IRanges(4, 6), 47 | compress=compress)), 48 | IRangesList(one=IRanges(c(1,3),c(5,8)), IRanges(), 49 | compress=compress)) 50 | } 51 | } 52 | 53 | test_IRangesList_as_list <- function() { 54 | for (compress in c(TRUE, FALSE)) { 55 | range1 <- IRanges(start=c(1,2,3), end=c(5,2,8)) 56 | range2 <- IRanges(start=c(15,45,20,1), end=c(15,100,80,5)) 57 | checkIdentical(list(range1, range2), 58 | as.list(IRangesList(range1, range2, compress=compress))) 59 | checkIdentical(list(a=range1, b=range2), 60 | as.list(IRangesList(a=range1, b=range2, compress=compress))) 61 | } 62 | } 63 | 64 | test_IRangesList_as_data_frame <- function() { 65 | for (compress in c(TRUE, FALSE)) { 66 | range1 <- IRanges(start=c(1,2,3), end=c(5,2,8)) 67 | range2 <- IRanges(start=c(15,45,20,1), end=c(15,100,80,5)) 68 | rl <- IRangesList(range1, range2, compress=compress) 69 | df <- data.frame(group=togroup(PartitioningByWidth(rl)), 70 | group_name=NA_character_, 71 | as.data.frame(c(range1,range2)), stringsAsFactors=FALSE) 72 | checkIdentical(df, as.data.frame(rl)) 73 | names(rl) <- c("a", "b") 74 | df$group_name <- c("a", "b")[togroup(PartitioningByWidth(rl))] 75 | checkIdentical(df, as.data.frame(rl)) 76 | } 77 | } 78 | 79 | test_IRangesList_annotation <- function() { 80 | range1 <- IRanges(start=c(1,2,3), end=c(5,2,8)) 81 | range2 <- IRanges(start=c(15,45,20,1), end=c(15,100,80,5)) 82 | for (compress in c(TRUE, FALSE)) { 83 | rl <- IRangesList(range1, range2, compress = compress) 84 | mcols(rl) <- DataFrame(a = 1:2) 85 | checkIdentical(mcols(rl)[,1], 1:2) 86 | checkIdentical(mcols(rl[2:1])[,1], 2:1) 87 | checkIdentical(mcols(c(rl,rl))[,1], rep(1:2,2)) 88 | checkIdentical(mcols(append(rl,rl))[,1], rep(1:2,2)) 89 | } 90 | } 91 | 92 | ## test_IRangesList_overlap <- function() { 93 | ## rl1 <- IRangesList(a = IRanges(c(1,2),c(4,3)), b = IRanges(c(4,6),c(10,7))) 94 | ## rl2 <- IRangesList(b = IRanges(c(0,2),c(4,5)), a = IRanges(c(4,5),c(6,7))) 95 | ## overlap(rl1, rl2) 96 | ## overlap(rl1, rl2, select = "first") 97 | ## overlap(rl1, rl2, select = "first", drop = TRUE) 98 | ## names(rl2)[1] <- "c" 99 | ## overlap(rl1, rl2) 100 | ## overlap(rl1, rl2, select = "first") 101 | ## overlap(rl1, rl2, select = "first", drop = TRUE) 102 | ## names(rl2) <- NULL 103 | ## overlap(rl1, rl2) 104 | ## overlap(rl1, rl2, select = "first") 105 | ## overlap(rl1, rl2, select = "first", drop = TRUE) 106 | ## overlap(rl1, rl2[1]) 107 | ## overlap(rl1, rl2[1], select = "first") 108 | ## overlap(rl1, rl2[1], select = "first", drop = TRUE) 109 | ## overlap(rl1[1], rl2) 110 | ## overlap(rl1[1], rl2, select = "first") 111 | ## overlap(rl1[1], rl2, select = "first", drop = TRUE) 112 | ## } 113 | 114 | -------------------------------------------------------------------------------- /inst/unitTests/test_Ranges-comparison.R: -------------------------------------------------------------------------------- 1 | test_pcompare_IntegerRanges <- function() 2 | { 3 | x1 <- IRanges(6:16, width=4) 4 | y <- IRanges(11, 14) 5 | target <- c(-6:-4, -4L, -4L, 0L, 4L, 4L, 4:6) 6 | checkIdentical(target, pcompare(x1, y)) 7 | checkIdentical(-target, pcompare(y, x1)) 8 | 9 | x2 <- IRanges(4:16, width=6) 10 | target <- c(-6:-4, -4L, -4L, -3L, -2L, 1L, 4L, 4L, 4:6) 11 | checkIdentical(target, pcompare(x2, y)) 12 | checkIdentical(-target, pcompare(y, x2)) 13 | 14 | x3 <- IRanges(8:16, width=2) 15 | target <- c(-6:-4, -1L, 2L, 3L, 4:6) 16 | checkIdentical(target, pcompare(x3, y)) 17 | checkIdentical(-target, pcompare(y, x3)) 18 | 19 | ## Moving a 0-width range over a non 0-width range. 20 | ## Note that when the end of the 0-width range is equal to the start of 21 | ## the non 0-width range minus 1, returning code -5 (which describes 22 | ## a situation of adjacent ranges) seems appropriate. 23 | ## However, one could argue that returning code -1 (which describes a 24 | ## situation where one range is inside the other) would also be 25 | ## appropriate, because, in that case, the two ranges have the same start. 26 | ## So the question really is whether the 0-width range should be considered 27 | ## *outside* or *inside* the non 0-width range. 28 | ## It's an arbitrary choice and we chose the former. 29 | x0 <- IRanges(10:16, width=0) 30 | target <- c(-6:-5, 2L, 2L, 2L, 5:6) 31 | checkIdentical(target, pcompare(x0, y)) 32 | checkIdentical(-target, pcompare(y, x0)) 33 | 34 | ## Moving a 0-width range over a 0-width range. 35 | y0 <- IRanges(13, 12) 36 | target <- c(-6L, -6L, -6L, 0L, 6L, 6L, 6L) 37 | checkIdentical(target, pcompare(x0, y0)) 38 | checkIdentical(-target, pcompare(y0, x0)) 39 | } 40 | 41 | test_order_IntegerRanges <- function() 42 | { 43 | ir1 <- IRanges(c(2,5,1,5), c(3,7,3,6)) 44 | ir1.sort <- IRanges(c(1,2,5,5), c(3,3,6,7)) 45 | ir1.rev <- IRanges(c(5,5,2,1), c(7,6,3,3)) 46 | checkIdentical(sort(ir1), ir1.sort) 47 | checkIdentical(sort(ir1, decreasing=TRUE), ir1.rev) 48 | checkException(sort(ir1, decreasing=NA), silent = TRUE) 49 | } 50 | 51 | -------------------------------------------------------------------------------- /inst/unitTests/test_RleViewsList.R: -------------------------------------------------------------------------------- 1 | test_RleViewsList <- function() { 2 | x1 <- rep(c(1L, 3L, NA, 7L, 9L), 1:5) 3 | x1Rle <- Rle(x1) 4 | x1Ranges <- IRanges(start = c(1, 3, 5, 7, 9), end = c(1, 13, 11, 10, 9)) 5 | x2 <- rev(x1) 6 | x2Rle <- Rle(x2) 7 | x2Ranges <- IRanges(start = c(2, 4, 6, 8, 10), end = c(3, 9, 11, 13, 15)) 8 | checkIdentical(RleViewsList(Views(x1Rle, x1Ranges), Views(x2Rle, x2Ranges)), 9 | RleViewsList(rleList = RleList(x1Rle, x2Rle), 10 | rangesList = IRangesList(x1Ranges, x2Ranges))) 11 | xRleViewsList <- RleViewsList(a = Views(x1Rle, x1Ranges), b = Views(x2Rle, x2Ranges)) 12 | xList <- 13 | list(a = lapply(seq_len(length(xRleViewsList[[1]])), 14 | function(i) window(x1, start = start(x1Ranges)[i], 15 | end = end(x1Ranges)[i])), 16 | b = lapply(seq_len(length(xRleViewsList[[2]])), 17 | function(i) window(x2, start = start(x2Ranges)[i], 18 | end = end(x2Ranges)[i]))) 19 | checkIdentical(c("a", "b"), names(viewApply(xRleViewsList, min))) 20 | checkIdentical(c("a", "b"), names(viewMins(xRleViewsList))) 21 | checkIdentical(c("a", "b"), names(viewMaxs(xRleViewsList))) 22 | checkIdentical(c("a", "b"), names(viewSums(xRleViewsList))) 23 | checkIdentical(c("a", "b"), names(viewMeans(xRleViewsList))) 24 | checkIdentical(c("a", "b"), names(viewWhichMins(xRleViewsList))) 25 | checkIdentical(c("a", "b"), names(viewWhichMaxs(xRleViewsList))) 26 | checkIdentical(c("a", "b"), names(viewRangeMins(xRleViewsList))) 27 | checkIdentical(c("a", "b"), names(viewRangeMaxs(xRleViewsList))) 28 | 29 | checkEqualsNumeric(unlist(lapply(xList, lapply, min)), unlist(viewMins(xRleViewsList))) 30 | checkEqualsNumeric(unlist(lapply(xList, lapply, min)), unlist(viewApply(xRleViewsList, min))) 31 | checkEqualsNumeric(unlist(lapply(xList, lapply, min, na.rm = TRUE)), unlist(viewMins(xRleViewsList, na.rm = TRUE))) 32 | checkEqualsNumeric(unlist(lapply(xList, lapply, min, na.rm = TRUE)), unlist(viewApply(xRleViewsList, min, na.rm = TRUE))) 33 | checkEqualsNumeric(unlist(lapply(xList, lapply, max)), unlist(viewMaxs(xRleViewsList))) 34 | checkEqualsNumeric(unlist(lapply(xList, lapply, max)), unlist(viewApply(xRleViewsList, max))) 35 | checkEqualsNumeric(unlist(lapply(xList, lapply, max, na.rm = TRUE)), unlist(viewMaxs(xRleViewsList, na.rm = TRUE))) 36 | checkEqualsNumeric(unlist(lapply(xList, lapply, max, na.rm = TRUE)), unlist(viewApply(xRleViewsList, max, na.rm = TRUE))) 37 | checkEqualsNumeric(unlist(lapply(xList, lapply, sum)), unlist(viewSums(xRleViewsList))) 38 | checkEqualsNumeric(unlist(lapply(xList, lapply, mean)), unlist(viewMeans(xRleViewsList))) 39 | checkEqualsNumeric(unlist(lapply(xList, lapply, sum)), unlist(viewApply(xRleViewsList, sum))) 40 | checkEqualsNumeric(unlist(lapply(xList, lapply, sum, na.rm = TRUE)), unlist(viewSums(xRleViewsList, na.rm = TRUE))) 41 | checkEqualsNumeric(unlist(lapply(xList, lapply, mean, na.rm = TRUE)), unlist(viewMeans(xRleViewsList, na.rm = TRUE))) 42 | checkEqualsNumeric(unlist(lapply(xList, lapply, sum, na.rm = TRUE)), unlist(viewApply(xRleViewsList, sum, na.rm = TRUE))) 43 | 44 | y1 <- rep(c(1.2, 3.4, NA, 7.8, 9.0), 1:5) 45 | y1Ranges <- IRanges(start = c(1, 3, 5, 7, 9), end = c(1, 13, 11, 10, 9)) 46 | y1Rle <- Rle(y1) 47 | y2 <- rev(y1) 48 | y2Rle <- Rle(y2) 49 | y2Ranges <- IRanges(start = c(2, 4, 6, 8, 10), end = c(3, 9, 11, 13, 15)) 50 | checkIdentical(RleViewsList(Views(y1Rle, y1Ranges), Views(y2Rle, y2Ranges)), 51 | RleViewsList(rleList = RleList(y1Rle, y2Rle), 52 | rangesList = IRangesList(y1Ranges, y2Ranges))) 53 | yRleViewsList <- RleViewsList(Views(y1Rle, y1Ranges), Views(y2Rle, y2Ranges)) 54 | yList <- 55 | list(lapply(seq_len(length(yRleViewsList[[1]])), 56 | function(i) window(y1, start = start(y1Ranges)[i], 57 | end = end(y1Ranges)[i])), 58 | lapply(seq_len(length(yRleViewsList[[2]])), 59 | function(i) window(y2, start = start(y2Ranges)[i], 60 | end = end(y2Ranges)[i]))) 61 | checkEqualsNumeric(unlist(lapply(yList, lapply, min)), unlist(viewMins(yRleViewsList))) 62 | checkEqualsNumeric(unlist(lapply(yList, lapply, min)), unlist(viewApply(yRleViewsList, min))) 63 | checkEqualsNumeric(unlist(lapply(yList, lapply, min, na.rm = TRUE)), unlist(viewMins(yRleViewsList, na.rm = TRUE))) 64 | checkEqualsNumeric(unlist(lapply(yList, lapply, min, na.rm = TRUE)), unlist(viewApply(yRleViewsList, min, na.rm = TRUE))) 65 | checkEqualsNumeric(unlist(lapply(yList, lapply, max)), unlist(viewMaxs(yRleViewsList))) 66 | checkEqualsNumeric(unlist(lapply(yList, lapply, max)), unlist(viewApply(yRleViewsList, max))) 67 | checkEqualsNumeric(unlist(lapply(yList, lapply, max, na.rm = TRUE)), unlist(viewMaxs(yRleViewsList, na.rm = TRUE))) 68 | checkEqualsNumeric(unlist(lapply(yList, lapply, max, na.rm = TRUE)), unlist(viewApply(yRleViewsList, max, na.rm = TRUE))) 69 | checkEqualsNumeric(unlist(lapply(yList, lapply, sum)), unlist(viewSums(yRleViewsList))) 70 | checkEqualsNumeric(unlist(lapply(yList, lapply, mean)), unlist(viewMeans(yRleViewsList))) 71 | checkEqualsNumeric(unlist(lapply(yList, lapply, sum)), unlist(viewApply(yRleViewsList, sum))) 72 | checkEqualsNumeric(unlist(lapply(yList, lapply, sum, na.rm = TRUE)), unlist(viewSums(yRleViewsList, na.rm = TRUE))) 73 | checkEqualsNumeric(unlist(lapply(yList, lapply, mean, na.rm = TRUE)), unlist(viewMeans(yRleViewsList, na.rm = TRUE))) 74 | checkEqualsNumeric(unlist(lapply(yList, lapply, sum, na.rm = TRUE)), unlist(viewApply(yRleViewsList, sum, na.rm = TRUE))) 75 | } 76 | -------------------------------------------------------------------------------- /inst/unitTests/test_coverage-methods.R: -------------------------------------------------------------------------------- 1 | test_IRanges_coverage <- function() { 2 | ir <- IRanges(c(1, 8, 14, 15, 19, 34, 40), width = c(12, 6, 6, 15, 6, 2, 7)) 3 | checkIdentical(as.vector(coverage(ir)), 4 | rep(c(1L, 2L, 1L, 2L, 3L, 2L, 1L, 0L, 1L, 0L, 1L), 5 | c(7, 5, 2, 4, 1, 5, 5, 4, 2, 4, 7))) 6 | ir <- IRanges(start=c(-2L, 6L, 9L, -4L, 1L, 0L, -6L, 10L), 7 | width=c( 5L, 0L, 6L, 1L, 4L, 3L, 2L, 3L)) 8 | checkIdentical(as.vector(coverage(ir)), 9 | rep(c(3L, 1L, 0L, 1L, 2L, 1L), c(2, 2, 4, 1, 3, 2))) 10 | checkIdentical(as.vector(coverage(ir, shift=7)), 11 | rep(c(1L, 0L, 1L, 2L, 3L, 1L, 0L, 1L, 2L, 1L), 12 | c(3, 1, 2, 1, 2, 2, 4, 1, 3, 2))) 13 | checkIdentical(as.vector(coverage(ir, shift=7, width=27)), 14 | rep(c(1L, 0L, 1L, 2L, 3L, 1L, 0L, 1L, 2L, 1L, 0L), 15 | c(3, 1, 2, 1, 2, 2, 4, 1, 3, 2, 6))) 16 | } 17 | 18 | -------------------------------------------------------------------------------- /inst/unitTests/test_extractList.R: -------------------------------------------------------------------------------- 1 | ### 2 | 3 | test_relistToClass <- function() 4 | { 5 | ## TODO 6 | } 7 | 8 | test_relist <- function() 9 | { 10 | ## TODO 11 | } 12 | 13 | test_splitAsList <- function() 14 | { 15 | ## TODO 16 | } 17 | 18 | test_extractList <- function() 19 | { 20 | ## TODO 21 | } 22 | 23 | -------------------------------------------------------------------------------- /inst/unitTests/test_findOverlaps-methods.R: -------------------------------------------------------------------------------- 1 | ### 2 | 3 | test_findOverlaps_IntegerRanges <- function() 4 | { 5 | ## ..... 6 | ## .... 7 | ## .. 8 | ## x 9 | ## xx 10 | ## xxx 11 | query <- IRanges(c(1, 4, 9), c(5, 7, 10)) 12 | subject <- IRanges(c(2, 2, 10), c(2, 3, 12)) 13 | 14 | result <- findOverlaps(query, subject, select = "first") 15 | checkIdentical(result, c(1L, NA, 3L)) 16 | result <- findOverlaps(query, subject, select = "last") 17 | checkIdentical(result, c(2L, NA, 3L)) 18 | result <- findOverlaps(query, subject, select = "arbitrary") 19 | checkIdentical(result, c(2L, NA, 3L)) 20 | 21 | checkOverlap <- function(a, q, s, r, c, self=FALSE) { 22 | target <- Hits(q, s, r, c, sort.by.query=TRUE) 23 | if (self) 24 | target <- as(target, "SortedByQuerySelfHits") 25 | checkIdentical(t(a), t(target)) 26 | } 27 | 28 | result <- findOverlaps(query, subject) 29 | checkOverlap(result, c(1, 1, 3), c(1, 2, 3), 3, 3) 30 | 31 | ## with 'maxgap' 32 | result <- findOverlaps(query, subject, maxgap = 0L) 33 | checkOverlap(result, c(1, 1, 2, 3), c(2, 1, 2, 3), 3, 3) 34 | 35 | ## with 'minoverlap' 36 | result <- findOverlaps(query, subject, minoverlap = 3L) 37 | checkOverlap(result, integer(0), integer(0), 3, 3) 38 | result <- findOverlaps(query, subject, minoverlap = 2L) 39 | checkOverlap(result, 1, 2, 3, 3) 40 | result <- findOverlaps(query, subject, minoverlap = 2L, select = "first") 41 | checkIdentical(result, c(2L, NA, NA)) 42 | result <- findOverlaps(query, subject, minoverlap = 2L, select = "last") 43 | checkIdentical(result, c(2L, NA, NA)) 44 | result <- findOverlaps(query, subject, minoverlap = 2L, select = "arbitrary") 45 | checkIdentical(result, c(2L, NA, NA)) 46 | 47 | ## zero-width ranges 48 | query <- IRanges(9:14, 8:13) 49 | result <- findOverlaps(query, subject, minoverlap = 1L) 50 | checkOverlap(result, integer(0), integer(0), 6, 3) 51 | result <- findOverlaps(query, subject) 52 | checkOverlap(result, c(3, 4), c(3, 3), 6, 3) 53 | result <- findOverlaps(query, subject, maxgap = 0L) 54 | checkOverlap(result, 2:5, c(3, 3, 3, 3), 6, 3) 55 | result <- findOverlaps(query, subject, maxgap = 1L) 56 | checkOverlap(result, 1:6, c(3, 3, 3, 3, 3, 3), 6, 3) 57 | result <- findOverlaps(subject, query, minoverlap = 1L) 58 | checkOverlap(result, integer(0), integer(0), 3, 6) 59 | result <- findOverlaps(subject, query) 60 | checkOverlap(result, c(3, 3), c(3, 4), 3, 6) 61 | result <- findOverlaps(subject, query, maxgap = 0L) 62 | checkOverlap(result, c(3, 3, 3, 3), 2:5, 3, 6) 63 | result <- findOverlaps(subject, query, maxgap = 1L) 64 | checkOverlap(result, c(3, 3, 3, 3, 3, 3), 1:6, 3, 6) 65 | 66 | ## ..... 67 | ## .... 68 | ## .. 69 | ## xxxx 70 | ## xxx 71 | query <- IRanges(c(1, 4, 9), c(5, 7, 10)) 72 | subject <- IRanges(c(2, 2), c(5, 4)) 73 | 74 | result <- findOverlaps(query, subject) 75 | checkOverlap(result, c(1, 1, 2, 2), c(1, 2, 1, 2), 3, 2) 76 | 77 | result <- findOverlaps(subject, query) 78 | checkOverlap(result, c(1, 1, 2, 2), c(1, 2, 1, 2), 2, 3) 79 | 80 | query <- IRanges(c(1, 4, 9, 11), c(5, 7, 10, 11)) 81 | 82 | result <- findOverlaps(query) 83 | checkOverlap(result, c(1, 1, 2, 2, 3, 4), c(1, 2, 1, 2, 3, 4), 4, 4, TRUE) 84 | 85 | ## check case of identical subjects 86 | ## ..... 87 | ## ..... 88 | ## .. 89 | ## xxxx 90 | ## xxxx 91 | ## xx 92 | ## xxx 93 | ## xx 94 | query <- IRanges(c(1, 4, 9), c(5, 7, 10)) 95 | subject <- IRanges(c(2, 2, 6, 6, 6), c(5, 5, 7, 8, 7)) 96 | result <- findOverlaps(query, subject) 97 | checkOverlap(result, c(1, 1, 2, 2, 2, 2, 2), c(1, 2, 1, 2, 3, 4, 5), 3, 5) 98 | 99 | subject <- IRanges(c(1, 6, 13), c(4, 9, 14)) # single points 100 | checkIdentical(findOverlaps(c(3L, 7L, 10L), subject, select = "first"), 101 | c(1L, 2L, NA)) 102 | checkIdentical(findOverlaps(c(3L, 7L, 10L), subject, select = "last"), 103 | c(1L, 2L, NA)) 104 | checkIdentical(findOverlaps(c(3L, 7L, 10L), subject, select = "arbitrary"), 105 | c(1L, 2L, NA)) 106 | checkIdentical(findOverlaps(IRanges(c(2,1),c(3,4)), subject), 107 | Hits(1:2, c(1, 1), 2, 3, sort.by.query=TRUE)) 108 | 109 | ## check other types of matching 110 | 111 | ## .. 112 | ## .. 113 | ## .... 114 | ## ...... 115 | ## xxxx 116 | ## xxxx 117 | ## xxxxx 118 | ## xxxx 119 | 120 | query <- IRanges(c(1, 5, 3, 4), width=c(2, 2, 4, 6)) 121 | subject <- IRanges(c(1, 3, 5, 6), width=c(4, 4, 5, 4)) 122 | 123 | ## 'start' 124 | result <- findOverlaps(query, subject, type = "start") 125 | checkOverlap(result, c(1, 2, 3), c(1, 3, 2), 4, 4) 126 | 127 | ## minoverlap > 1L 128 | result <- findOverlaps(query, subject, type = "start", minoverlap = 3L) 129 | checkOverlap(result, 3, 2, 4, 4) 130 | 131 | ## 'end' 132 | result <- findOverlaps(query, subject, type = "end") 133 | checkOverlap(result, c(2, 3, 4, 4), c(2, 2, 3, 4), 4, 4) 134 | result <- findOverlaps(subject, query, type = "end") 135 | checkOverlap(result, c(2, 2, 3, 4), c(2, 3, 4, 4), 4, 4) 136 | 137 | ## select = "first" 138 | result <- findOverlaps(query, subject, type = "end", select = "first") 139 | checkIdentical(result, c(NA, 2L, 2L, 3L)) 140 | 141 | ## 'within' 142 | result <- findOverlaps(query, subject, type = "within") 143 | checkOverlap(result, c(1, 2, 2, 3), c(1, 2, 3, 2), 4, 4) 144 | 145 | ## 'equal' 146 | result <- findOverlaps(query, subject, type = "equal") 147 | checkOverlap(result, 3, 2, 4, 4) 148 | 149 | checkException(findOverlaps(query, NULL), silent = TRUE) 150 | checkException(findOverlaps(NULL, query), silent = TRUE) 151 | } 152 | 153 | test_subsetByOverlaps_IntegerRanges <- function() { 154 | x <- IRanges(9:12, 15) 155 | ranges <- IRanges(1, 10) 156 | checkIdentical(x[1:2], subsetByOverlaps(x, ranges)) 157 | checkIdentical(x[3:4], subsetByOverlaps(x, ranges, invert=TRUE)) 158 | checkIdentical(x[1:3], subsetByOverlaps(x, ranges, maxgap=0)) 159 | checkIdentical(x[4], subsetByOverlaps(x, ranges, maxgap=0, invert=TRUE)) 160 | 161 | x <- IRanges(c(1, 4, 9), c(5, 7, 10)) 162 | ranges <- IRanges(c(6, 8, 10), c(7, 12, 14)) 163 | checkIdentical(x[2:3], subsetByOverlaps(x, ranges)) 164 | checkIdentical(x[1], subsetByOverlaps(x, ranges, invert=TRUE)) 165 | checkIdentical(x, subsetByOverlaps(x, ranges, maxgap=0)) 166 | checkIdentical(x[0], subsetByOverlaps(x, ranges, maxgap=0, invert=TRUE)) 167 | } 168 | 169 | -------------------------------------------------------------------------------- /inst/unitTests/test_nearest-methods.R: -------------------------------------------------------------------------------- 1 | checkMatching <- function(a, q, s, r, c) 2 | { 3 | mat <- cbind(queryHits = as.integer(q), subjectHits = as.integer(s)) 4 | checkIdentical(as.matrix(a), mat) 5 | checkIdentical(c(queryLength(a), subjectLength(a)), as.integer(c(r, c))) 6 | } 7 | 8 | test_precede_follow_IntegerRanges <- function() 9 | { 10 | query <- IRanges(c(1, 3, 9), c(3, 7, 10)) 11 | subject <- IRanges(c(3, 10, 2), c(3, 12, 5)) 12 | 13 | checkIdentical(precede(query, subject), c(2L, 2L, NA)) 14 | checkIdentical(precede(IRanges(), subject), integer()) 15 | checkIdentical(precede(query, IRanges()), rep(NA_integer_, 3)) 16 | checkIdentical(precede(query), c(3L, 3L, NA)) 17 | 18 | checkIdentical(follow(query, subject), c(NA, NA, 3L)) 19 | checkIdentical(follow(IRanges(), subject), integer()) 20 | checkIdentical(follow(query, IRanges()), rep(NA_integer_, 3)) 21 | checkIdentical(follow(query), c(NA, NA, 2L)) 22 | 23 | checkMatching(precede(query, subject, select="all"), 24 | c(1, 2), c(2, 2), 3, 3) 25 | 26 | ## xxxx 27 | ## xxx 28 | ## xx 29 | ## xx 30 | ## xxx 31 | ## .. 32 | ## .. 33 | ## .. 34 | ## .. 35 | ## .. 36 | 37 | subject <- IRanges(c(1, 2, 9, 15, 15), width=c(4, 3, 2, 2, 3)) 38 | query <- IRanges(c(6, 11, 1, 13, 18), width=c(2, 2, 2, 2, 2)) 39 | 40 | checkMatching(precede(query, subject, select="all"), 41 | c(1, 2, 2, 3, 4, 4), c(3, 4, 5, 3, 4, 5), 5, 5) 42 | checkMatching(precede(subject, query, select="all"), 43 | c(1, 2, 3, 4, 5), c(1, 1, 2, 5, 5), 5, 5) 44 | 45 | checkMatching(follow(query, subject, select="all"), 46 | c(1, 1, 2, 4, 5), c(1, 2, 3, 3, 5), 5, 5) 47 | checkMatching(follow(subject, query, select="all"), 48 | c(3, 4, 5), c(1, 4, 4), 5, 5) 49 | 50 | checkMatching(precede(query, select="all"), 51 | c(1, 2, 3, 4), c(2, 4, 1, 5), 5, 5) 52 | checkMatching(precede(subject, select="all"), 53 | c(1, 2, 3, 3), c(3, 3, 4, 5), 5, 5) 54 | 55 | checkMatching(follow(query, select="all"), 56 | c(1, 2, 4, 5), c(3, 1, 2, 4), 5, 5) 57 | checkMatching(follow(subject, select="all"), 58 | c(3, 3, 4, 5), c(1, 2, 3, 3), 5, 5) 59 | } 60 | 61 | test_nearest_IntegerRanges <- function() 62 | { 63 | query <- IRanges(c(1, 3, 9), c(2, 7, 10)) 64 | subject <- IRanges(c(3, 5, 12), c(3, 6, 12)) 65 | 66 | ## 2 possible results 67 | current <- nearest(query, subject) 68 | target1 <- c(1L, 1L, 3L) 69 | target2 <- c(1L, 2L, 3L) 70 | checkTrue(identical(target1, current) || identical(target2, current)) 71 | checkIdentical(nearest(query), c(2L, 1L, 2L)) 72 | checkIdentical(nearest(query, subject[c(2,3,1)]), c(3L, 3L, 2L)) 73 | 74 | ## xxxx 75 | ## xxx 76 | ## xx 77 | ## xx 78 | ## xxx 79 | ## .. 80 | ## .. 81 | ## .. 82 | ## .. 83 | ## .. 84 | 85 | subject <- IRanges(c(1, 2, 9, 15, 15), width=c(4, 3, 2, 2, 3)) 86 | query <- IRanges(c(6, 11, 1, 13, 18), width=c(2, 2, 2, 2, 2)) 87 | 88 | checkMatching(nearest(query, subject, select = "all"), 89 | c(1, 1, 1, 2, 3, 3, 4, 4, 5), 90 | c(1, 2, 3, 3, 1, 2, 4, 5, 5), 5, 5) 91 | checkMatching(nearest(subject, query, select = "all"), 92 | c(1, 2, 3, 4, 5, 5), c(3, 3, 2, 4, 4, 5), 5, 5) 93 | 94 | checkMatching(nearest(subject, select="all"), 95 | c(1, 2, 3, 3, 3, 3, 4, 5), c(2, 1, 1, 2, 4, 5, 5, 4), 5, 5) 96 | checkMatching(nearest(query, select="all"), 97 | c(1, 1, 2, 3, 4, 5), c(2, 3, 4, 1, 2, 4), 5, 5) 98 | } 99 | 100 | quiet <- suppressWarnings 101 | test_distance_IntegerRanges <- function() 102 | { 103 | checkIdentical(quiet(distance(IRanges(), IRanges())), integer()) 104 | 105 | ## adjacent, overlap, separated by 1 106 | query <- IRanges(c(1, 3, 9), c(2, 7, 10)) 107 | subject <- IRanges(c(3, 5, 12), c(3, 6, 12)) 108 | checkIdentical(quiet(distance(query, subject)), c(0L, 0L, 1L)) 109 | ## recycling 110 | checkIdentical(quiet(distance(query[1:2], subject)), 111 | c(0L, 0L, 9L)) 112 | ## zero-width 113 | target <- abs(-3:3) 114 | current <- sapply(-3:3, function(i) 115 | quiet(distance(shift(IRanges(4,3), i), IRanges(4,3)))) 116 | checkIdentical(target, current) 117 | checkIdentical(quiet(distance(IRanges(4,3), IRanges(3,4))), 0L) 118 | } 119 | 120 | test_distanceToNearest_IntegerRanges <- function() 121 | { 122 | target <- Hits(sort.by.query=TRUE) 123 | current <- distanceToNearest(IRanges(), IRanges()) 124 | checkIdentical(queryHits(current), queryHits(target)) 125 | checkIdentical(subjectHits(current), subjectHits(target)) 126 | checkIdentical(queryLength(current), queryLength(target)) 127 | 128 | x <- IRanges(5, 10) 129 | subject <- IRanges(c(1, 1, 1), c(4, 5, 6)) 130 | current <- distanceToNearest(x, subject, select="all") 131 | checkIdentical(subjectHits(current), 1:3) 132 | 133 | current <- distanceToNearest(x, rev(subject), select="all") 134 | checkIdentical(subjectHits(current), 1:3) 135 | 136 | current <- distanceToNearest(x, IRanges()) 137 | checkIdentical(length(current), 0L) 138 | checkIdentical(queryLength(current), 1L) 139 | checkIdentical(subjectLength(current), 0L) 140 | 141 | x <- IRanges(c(2, 4, 12, 15), c(2, 3, 13, 14)) 142 | subject <- IRanges(1, 10) 143 | current <- distanceToNearest(x, subject) 144 | checkIdentical(queryHits(current), 1:4) 145 | checkIdentical(mcols(current)$distance, c(0L, 0L, 1L, 4L)) 146 | } 147 | 148 | -------------------------------------------------------------------------------- /inst/unitTests/test_seqapply.R: -------------------------------------------------------------------------------- 1 | test_unsplit <- function() { 2 | ir <- IRanges(1:5, 11:15) 3 | f <- factor(c("a", "b", "a", "b", "b"), c("b", "a", "c")) 4 | 5 | rl <- split(ir, f) 6 | checkIdentical(unsplit(rl, f), ir) 7 | 8 | rl <- split(ir, f, drop=TRUE) 9 | checkIdentical(unsplit(rl, Rle(f), drop=TRUE), ir) 10 | checkException(unsplit(rl, f, drop=FALSE), silent=TRUE) 11 | 12 | v <- 1:5 13 | l <- splitAsList(v, f) 14 | checkIdentical(unsplit(l, Rle(f)), v) 15 | 16 | names(ir) <- letters[1:5] 17 | rl <- split(ir, f) 18 | checkIdentical(unsplit(rl, f), ir) 19 | 20 | df <- DataFrame(unname(ir), row.names=names(ir)) 21 | dfl <- split(df, f) 22 | checkIdentical(unsplit(dfl, f), df) 23 | 24 | ir <- IRanges(1:5, 11:15) 25 | names(ir)[c(1,3,5)] <- letters[1:3] 26 | rl <- split(ir, f) 27 | checkIdentical(unsplit(rl, f), ir) 28 | } 29 | 30 | -------------------------------------------------------------------------------- /inst/unitTests/test_setops-methods.R: -------------------------------------------------------------------------------- 1 | test_IRanges_union <- function() { 2 | x <- IRanges(c(1, 4, 9), c(5, 7, 10)) 3 | y <- IRanges(c(2, 2, 10), c(2, 3, 12)) 4 | ans <- union(x, y) 5 | ans0 <- IRanges(c(1, 9), c(7, 12)) 6 | checkIdentical(ans, ans0) 7 | } 8 | 9 | test_IRanges_intersect <- function() { 10 | x <- IRanges(c(1, 4, 9), c(5, 7, 10)) 11 | y <- IRanges(c(2, 2, 10), c(2, 3, 12)) 12 | ans <- intersect(x, y) 13 | ans0 <- IRanges(c(2,10),c(3,10)) 14 | checkIdentical(ans, ans0) 15 | } 16 | 17 | test_IRanges_setdiff <- function() { 18 | x <- IRanges(c(1, 4, 9), c(5, 7, 10)) 19 | y <- IRanges(c(2, 2, 10), c(2, 3, 12)) 20 | ans <- setdiff(x, y) 21 | ans0 <- IRanges(c(1,4,9), c(1,7,9)) 22 | checkIdentical(ans, ans0) 23 | ans <- setdiff(y, x) 24 | ans0 <- IRanges(c(11), c(12)) 25 | checkIdentical(ans, ans0) 26 | } 27 | 28 | test_IRanges_punion <- function() { 29 | x <- IRanges(start=c(1,11,21,31,41,51,61,71), end=c(5,10,25,35,40,55,65,75)) 30 | y <- IRanges(start=c(1, 8,18,35,43,48,63,78), end=c(4,15,22,36,45,50,62,79)) 31 | ans0 <- IRanges(start=c(1,8,18,31,41,48,61,71), end=c(5,15,25,36,45,55,65,79)) 32 | checkIdentical(punion(x, y, fill.gap=TRUE), ans0) 33 | checkIdentical(punion(y, x, fill.gap=TRUE), ans0) 34 | } 35 | 36 | test_IRanges_pintersect <- function() { 37 | x <- IRanges(start=c(22,22,22,22,22,22), end=c(28,28,28,28,21,21)) 38 | y <- IRanges(start=c(25,30,29,25,22,22), end=c(30,40,40,24,21,29)) 39 | ansMaxStart <- IRanges(start=c(25,30,29,25,22,22), end=c(28,29,28,24,21,21)) 40 | ansStartX <- IRanges(start=c(25,22,29,25,22,22), end=c(28,21,28,24,21,21)) 41 | ansStartY <- IRanges(start=c(25,30,29,25,22,22), end=c(28,29,28,24,21,21)) 42 | 43 | checkException(pintersect(x, y), silent = TRUE) 44 | checkException(pintersect(y, x), silent = TRUE) 45 | 46 | for (resolve.empty in c("none", "max.start", "start.x")) { 47 | checkIdentical(x, pintersect(x, x, resolve.empty = resolve.empty)) 48 | checkIdentical(y, pintersect(y, y, resolve.empty = resolve.empty)) 49 | } 50 | 51 | checkIdentical(pintersect(x[-c(2,3)], y[-c(2,3)]), ansMaxStart[-c(2,3)]) 52 | checkIdentical(pintersect(y[-c(2,3)], x[-c(2,3)]), ansMaxStart[-c(2,3)]) 53 | 54 | checkIdentical(pintersect(x, y, resolve.empty = "max.start"), ansMaxStart) 55 | checkIdentical(pintersect(y, x, resolve.empty = "max.start"), ansMaxStart) 56 | 57 | checkIdentical(pintersect(x, y, resolve.empty = "start.x"), ansStartX) 58 | checkIdentical(pintersect(y, x, resolve.empty = "start.x"), ansStartY) 59 | } 60 | 61 | test_IRanges_psetdiff <- function() { 62 | x <- IRanges(start=c(1,11,21,31,41,51,61,71), end=c(5,10,25,35,40,55,65,75)) 63 | y <- IRanges(start=c(1, 8,18,35,43,48,63,78), end=c(4,15,22,36,45,50,62,79)) 64 | 65 | ans <- psetdiff(x[-7], y[-7]) 66 | ans0 <- IRanges(start=c(5,11,23,31,41,51,71), end=c(5,10,25,34,40,55,75)) 67 | checkIdentical(ans, ans0) 68 | 69 | ans <- psetdiff(y[-2], x[-2]) 70 | ans0 <- IRanges(start=c(1,18,36,43,48,63,78), end=c(0,20,36,45,50,62,79)) 71 | checkIdentical(ans, ans0) 72 | } 73 | 74 | test_IRanges_pgap <- function() { 75 | x <- IRanges(start=c(1,11,21,31,41,51,61,71), end=c(5,10,25,35,40,55,65,75)) 76 | y <- IRanges(start=c(1, 8,18,35,43,48,63,78), end=c(4,15,22,36,45,50,62,79)) 77 | 78 | ans <- pgap(x, y) 79 | checkIdentical(width(ans), c(0L, 0L, 0L, 0L, 2L, 0L, 0L, 2L)) 80 | checkIdentical(start(ans)[width(ans) != 0L], c(41L, 76L)) 81 | } 82 | 83 | test_IntegerRangesList_setops <- function() { 84 | for (compress in c(TRUE, FALSE)) { 85 | rl1 <- IRangesList(IRanges(c(1,2),c(4,3)), IRanges(c(4,6),c(10,7)), 86 | compress=compress) 87 | rl2 <- IRangesList(IRanges(c(0,2),c(4,5)), IRanges(c(4,5),c(6,7)), 88 | compress=compress) 89 | checkIdentical(union(rl1, rl2), 90 | IRangesList(union(rl1[[1]], rl2[[1]]), 91 | union(rl1[[2]], rl2[[2]]), 92 | compress=compress)) 93 | checkIdentical(intersect(rl1, rl2), 94 | IRangesList(intersect(rl1[[1]], rl2[[1]]), 95 | intersect(rl1[[2]], rl2[[2]]), 96 | compress=compress)) 97 | checkIdentical(setdiff(rl1, rl2), 98 | IRangesList(setdiff(rl1[[1]], rl2[[1]]), 99 | setdiff(rl1[[2]], rl2[[2]]), 100 | compress=compress)) 101 | } 102 | } 103 | 104 | -------------------------------------------------------------------------------- /inst/unitTests/test_split.R: -------------------------------------------------------------------------------- 1 | test_splitAsList <- function() { 2 | ir <- IRanges(sample(100),sample(100)+100) 3 | ir2 <- unlist(split(ir, ceiling(1:100 / 10))) 4 | checkTrue(all(ir==ir2)) 5 | } 6 | -------------------------------------------------------------------------------- /inst/unitTests/test_splitListElements.R: -------------------------------------------------------------------------------- 1 | ### 2 | 3 | test_regroupBySupergroup <- function() 4 | { 5 | regroupBySupergroup <- IRanges:::regroupBySupergroup 6 | 7 | .do_checks <- function(x, breakpoints, target) 8 | { 9 | supergroups <- PartitioningByEnd(breakpoints) 10 | 11 | current <- regroupBySupergroup(x, supergroups) 12 | checkIdentical(target, current) 13 | checkIdentical(target, regroupBySupergroup(x, breakpoints)) 14 | 15 | x_partitioning <- PartitioningByEnd(x) 16 | current2 <- regroupBySupergroup(x_partitioning, supergroups) 17 | checkIdentical(PartitioningByEnd(target), current2) 18 | } 19 | 20 | x <- CharacterList( 21 | x1=NULL, 22 | x2=LETTERS[1:3], 23 | x3=LETTERS[4:5], 24 | x4=letters[1:5], 25 | x5=NULL, 26 | x6=letters[6:7] 27 | ) 28 | 29 | breakpoints <- c(SG1=3, SG2=6) 30 | target <- CharacterList(SG1=LETTERS[1:5], SG2=letters[1:7], 31 | compress=TRUE) 32 | .do_checks(as(x, "CompressedList"), breakpoints, target) 33 | .do_checks(as(x, "SimpleList"), breakpoints, target) 34 | 35 | breakpoints <- c(SG1=2, SG2=5, SG3=6) 36 | target <- CharacterList(SG1=LETTERS[1:3], 37 | SG2=c(LETTERS[4:5], letters[1:5]), 38 | SG3=letters[6:7], 39 | compress=TRUE) 40 | .do_checks(as(x, "CompressedList"), breakpoints, target) 41 | .do_checks(as(x, "SimpleList"), breakpoints, target) 42 | 43 | breakpoints <- c(SG1=2, 2, SG2=5, SG3=6) 44 | target <- CharacterList(SG1=LETTERS[1:3], 45 | NULL, 46 | SG2=c(LETTERS[4:5], letters[1:5]), 47 | SG3=letters[6:7], 48 | compress=TRUE) 49 | .do_checks(as(x, "CompressedList"), breakpoints, target) 50 | .do_checks(as(x, "SimpleList"), breakpoints, target) 51 | 52 | breakpoints <- 6 53 | target <- CharacterList(unlist(x, use.names=FALSE), compress=TRUE) 54 | .do_checks(as(x, "CompressedList"), breakpoints, target) 55 | .do_checks(as(x, "SimpleList"), breakpoints, target) 56 | 57 | breakpoints <- c(SG1=6, SG2=6, SG3=6) 58 | target <- CharacterList(SG1=unlist(x, use.names=FALSE), 59 | SG2=NULL, 60 | SG3=NULL, 61 | compress=TRUE) 62 | .do_checks(as(x, "CompressedList"), breakpoints, target) 63 | .do_checks(as(x, "SimpleList"), breakpoints, target) 64 | 65 | breakpoints <- c(0, 0, 0, 6, 6) 66 | target <- CharacterList(NULL, NULL, NULL, 67 | unlist(x, use.names=FALSE), 68 | NULL, 69 | compress=TRUE) 70 | .do_checks(as(x, "CompressedList"), breakpoints, target) 71 | .do_checks(as(x, "SimpleList"), breakpoints, target) 72 | 73 | breakpoints <- seq_along(x) 74 | target <- unname(as(x, "CompressedList")) 75 | .do_checks(as(x, "CompressedList"), breakpoints, target) 76 | .do_checks(as(x, "SimpleList"), breakpoints, target) 77 | 78 | names(breakpoints) <- names(x) 79 | target <- as(x, "CompressedList") 80 | .do_checks(as(x, "CompressedList"), breakpoints, target) # no-op 81 | .do_checks(as(x, "SimpleList"), breakpoints, target) 82 | 83 | x0 <- CharacterList() 84 | breakpoints <- setNames(integer(0), character(0)) 85 | target <- setNames(CharacterList(compress=TRUE), character(0)) 86 | .do_checks(as(x0, "CompressedList"), breakpoints, target) 87 | # Fails at the moment because unlist() is doesn't work properly on 88 | # SimpleCharacterList 89 | #.do_checks(as(x0, "SimpleList"), breakpoints, target) 90 | 91 | x2 <- RleList(Rle(44:45, 2:1), Rle(45), Rle(-2, 3)) 92 | breakpoints <- c(SG1=2, SG2=3) 93 | target <- RleList(SG1=Rle(44:45, c(2,2)), SG2=Rle(-2, 3), 94 | compress=TRUE) 95 | .do_checks(as(x2, "CompressedList"), breakpoints, target) 96 | .do_checks(as(x2, "SimpleList"), breakpoints, target) 97 | 98 | x3 <- Views(unlist(x2, use.names=FALSE), 99 | start=c(3, 1, 1), end=c(6, 1, 3)) 100 | breakpoints <- c(SG1=2, SG2=3) 101 | target <- RleList(SG1=Rle(c(45,-2,44), c(2,2,1)), SG2=Rle(44:45, 2:1), 102 | compress=TRUE) 103 | .do_checks(x3, breakpoints, target) 104 | } 105 | 106 | -------------------------------------------------------------------------------- /inst/unitTests/test_tile-methods.R: -------------------------------------------------------------------------------- 1 | test_tile <- function() { 2 | ir <- IRanges() 3 | checkIdentical(tile(ir, n=3), IRangesList()) 4 | checkIdentical(tile(ir, width=2), IRangesList()) 5 | checkIdentical(tile(ir, n=0), IRangesList()) 6 | ir <- IRanges(1, 4) 7 | checkIdentical(tile(ir, n=2), IRangesList(IRanges(c(1, 3), c(2, 4)))) 8 | checkIdentical(tile(ir, n=2), tile(ir, width=2)) 9 | ir <- IRanges(1, 5) 10 | checkIdentical(tile(ir, n=3), IRangesList(IRanges(c(1, 2, 4), c(1, 3, 5)))) 11 | checkIdentical(tile(ir, n=3), tile(ir, width=2)) 12 | ir <- IRanges(1, 4) 13 | checkIdentical(tile(ir, n=3), IRangesList(IRanges(1:3, c(1, 2, 4)))) 14 | ir <- IRanges(1:3, width=5:3) 15 | checkIdentical(tile(ir, n=3), 16 | IRangesList(IRanges(c(1, 2, 4), c(1, 3, 5)), 17 | IRanges(c(2, 3, 4), c(2, 3, 5)), 18 | IRanges(c(3, 4, 5), c(3, 4, 5)))) 19 | checkIdentical(tile(ir, width=2), 20 | IRangesList(IRanges(c(1, 2, 4), c(1, 3, 5)), 21 | IRanges(c(2, 4), c(3, 5)), 22 | IRanges(c(3, 4), c(3, 5)))) 23 | checkIdentical(elementNROWS(tile(ir, width=4)), c(2L, 1L, 1L)) 24 | checkException(tile(ir, n=4), silent=TRUE) 25 | checkException(tile(ir, width=-1), silent=TRUE) 26 | checkException(tile(ir, n=-1), silent=TRUE) 27 | ir <- setNames(IRanges(1:3, width = 10), letters[1:3]) 28 | checkIdentical(names(ir), names(tile(ir, n = 2))) 29 | checkIdentical(names(ir), names(tile(ir, width = 3))) 30 | } 31 | 32 | test_slidingWindows <- function() { 33 | ir <- IRanges() 34 | checkIdentical(slidingWindows(ir, width=3), IRangesList()) 35 | 36 | ir <- IRanges(1:3, width=5:3) 37 | checkIdentical(slidingWindows(ir, width=3, step=2), 38 | IRangesList(IRanges(c(1, 3), c(3, 5)), 39 | IRanges(c(2, 4), c(4, 5)), 40 | IRanges(3, 5))) 41 | ir <- setNames(IRanges(1:3, width = 10), letters[1:3]) 42 | checkIdentical(names(ir), names(slidingWindows(ir, width = 3))) 43 | } 44 | -------------------------------------------------------------------------------- /man/CompressedHitsList-class.Rd: -------------------------------------------------------------------------------- 1 | \name{CompressedHitsList-class} 2 | \docType{class} 3 | 4 | \alias{class:CompressedHitsList} 5 | \alias{CompressedHitsList-class} 6 | \alias{CompressedHitsList} 7 | 8 | % coercion 9 | \alias{as.matrix,CompressedHitsList-method} 10 | 11 | % accessors 12 | \alias{space,CompressedHitsList-method} 13 | \alias{from,CompressedHitsList-method} 14 | \alias{to,CompressedHitsList-method} 15 | \alias{nLnode,CompressedHitsList-method} 16 | \alias{nRnode,CompressedHitsList-method} 17 | 18 | 19 | \title{CompressedHitsList objects} 20 | \description{ 21 | An efficient representation of \link{HitsList} objects. 22 | See \code{?\link{HitsList}} for more information about \link{HitsList} 23 | objects. 24 | } 25 | 26 | \note{ 27 | This class is highly experimental. It has not been well tested and 28 | may disappear at any time. 29 | } 30 | 31 | \author{Michael Lawrence} 32 | 33 | \seealso{ 34 | \link{HitsList} objects. 35 | } 36 | 37 | \keyword{methods} 38 | \keyword{classes} 39 | -------------------------------------------------------------------------------- /man/Hits-class-leftovers.Rd: -------------------------------------------------------------------------------- 1 | \name{Hits-class-leftovers} 2 | \docType{class} 3 | 4 | \alias{Hits-examples} 5 | 6 | % coercion 7 | 8 | \alias{coerce,SortedByQueryHits,PartitioningByEnd-method} 9 | \alias{coerce,SortedByQueryHits,Partitioning-method} 10 | \alias{coerce,SortedByQueryHits,IntegerRanges-method} 11 | \alias{coerce,SortedByQueryHits,IRanges-method} 12 | 13 | \alias{coerce,SortedByQueryHits,CompressedIntegerList-method} 14 | \alias{coerce,SortedByQueryHits,IntegerList-method} 15 | \alias{coerce,SortedByQueryHits,List-method} 16 | \alias{as.list,SortedByQueryHits-method} 17 | 18 | \alias{coerce,Hits,CompressedIntegerList-method} 19 | \alias{coerce,Hits,IntegerList-method} 20 | \alias{coerce,Hits,List-method} 21 | \alias{as.list,Hits-method} 22 | \alias{coerce,Hits,Grouping} 23 | 24 | \title{Examples of basic manipulation of Hits objects} 25 | 26 | \description{ 27 | IMPORTANT NOTE - 4/29/2014: This man page is being refactored. Most of 28 | the things that used to be documented here have been moved to the man 29 | page for \link[S4Vectors]{Hits} objects located in the \pkg{S4Vectors} 30 | package. 31 | } 32 | 33 | \details{ 34 | The \code{as.data.frame} method coerces a \code{Hits} object to a two column 35 | \code{data.frame} with one row for each hit, where the value in the first 36 | column is the index of an element in the query and the value in the second 37 | column is the index of an element in the subject. 38 | } 39 | 40 | \section{Coercion}{ 41 | In the code snippets below, \code{x} is a \code{Hits} 42 | object. 43 | 44 | \describe{ 45 | \item{\code{as.list(x)}:}{ Coerces \code{x} to a list of integers, 46 | grouping the the right node hits for each left node. 47 | } 48 | \item{\code{as(x, "List")}:}{ Analogous to \code{as.list(x)}. 49 | } 50 | \item{\code{as(x, "Grouping")}:}{ Returns roughly the same object as 51 | \code{as(x, "List")}, except it is a ManyToManyGrouping, i.e., it 52 | knows the number of right nodes. 53 | } 54 | } 55 | } 56 | 57 | \seealso{ 58 | The \link[S4Vectors]{Hits} class defined and documented in the 59 | \pkg{S4Vectors} package. 60 | } 61 | \examples{ 62 | query <- IRanges(c(1, 4, 9), c(5, 7, 10)) 63 | subject <- IRanges(c(2, 2, 10), c(2, 3, 12)) 64 | hits <- findOverlaps(query, subject) 65 | 66 | as.matrix(hits) 67 | as.data.frame(hits) 68 | 69 | as.table(hits) # hits per query 70 | as.table(t(hits)) # hits per subject 71 | 72 | ## Turn a Hits object into an IntegerList object with one list element 73 | ## per element in the original query. 74 | as(hits, "IntegerList") 75 | as(hits, "List") # same as as(hits, "IntegerList") 76 | 77 | ## Turn a Hits object into a PartitioningByEnd object that describes 78 | ## the grouping of hits by query. 79 | as(hits, "PartitioningByEnd") 80 | as(hits, "Partitioning") # same as as(hits, "PartitioningByEnd") 81 | 82 | ## --------------------------------------------------------------------- 83 | ## remapHits() 84 | ## --------------------------------------------------------------------- 85 | 86 | hits2 <- remapHits(hits, 87 | Rnodes.remapping=factor(c("e", "e", "d"), letters[1:5])) 88 | hits2 89 | 90 | hits3 <- remapHits(hits, 91 | Rnodes.remapping=c(5, 5, 4), new.nRnode=5) 92 | hits3 93 | stopifnot(identical(hits2, hits3)) 94 | } 95 | \keyword{methods} 96 | \keyword{classes} 97 | -------------------------------------------------------------------------------- /man/IRanges-internals.Rd: -------------------------------------------------------------------------------- 1 | \name{IRanges internals} 2 | 3 | \alias{coerce,ANY,vector-method} 4 | 5 | 6 | \title{IRanges internals} 7 | 8 | \description{ 9 | Objects, classes and methods defined in the \pkg{IRanges} package 10 | that are not intended to be used directly. 11 | } 12 | 13 | \keyword{internal} 14 | \keyword{classes} 15 | \keyword{methods} 16 | -------------------------------------------------------------------------------- /man/IRanges-utils.Rd: -------------------------------------------------------------------------------- 1 | \name{IRanges-utils} 2 | 3 | \alias{IRanges-utils} 4 | 5 | \alias{successiveIRanges} 6 | \alias{breakInChunks} 7 | 8 | \alias{whichAsIRanges} 9 | 10 | % Coercion: 11 | \alias{asNormalIRanges} 12 | \alias{coerce,IRanges,NormalIRanges-method} 13 | 14 | \title{IRanges utility functions} 15 | 16 | \description{ 17 | Utility functions for creating or modifying \link{IRanges} objects. 18 | } 19 | 20 | \usage{ 21 | ## Create an IRanges instance: 22 | successiveIRanges(width, gapwidth=0, from=1) 23 | breakInChunks(totalsize, nchunk, chunksize) 24 | 25 | ## Turn a logical vector into a set of ranges: 26 | whichAsIRanges(x) 27 | 28 | ## Coercion: 29 | asNormalIRanges(x, force=TRUE) 30 | } 31 | 32 | \arguments{ 33 | \item{width}{ 34 | A vector of non-negative integers (with no NAs) specifying the widths 35 | of the ranges to create. 36 | } 37 | \item{gapwidth}{ 38 | A single integer or an integer vector with one less element than 39 | the \code{width} vector specifying the widths of the gaps separating 40 | one range from the next one. 41 | } 42 | \item{from}{ 43 | A single integer specifying the starting position of the first range. 44 | } 45 | \item{totalsize}{ 46 | A single non-negative integer. The total size of the object to break. 47 | } 48 | \item{nchunk}{ 49 | A single positive integer. The number of chunks. 50 | } 51 | \item{chunksize}{ 52 | A single positive integer. The size of the chunks (last chunk might be 53 | smaller). 54 | } 55 | \item{x}{ 56 | A logical vector for \code{whichAsIRanges}. 57 | 58 | An \link{IRanges} object for \code{asNormalIRanges}. 59 | } 60 | \item{force}{ 61 | \code{TRUE} or \code{FALSE}. Should \code{x} be turned into a 62 | \link{NormalIRanges} object even if \code{isNormal(x)} is \code{FALSE}? 63 | } 64 | } 65 | 66 | \details{ 67 | \code{successiveIRanges} returns an \link{IRanges} instance containing 68 | the ranges that have the widths specified in the \code{width} vector 69 | and are separated by the gaps specified in \code{gapwidth}. 70 | The first range starts at position \code{from}. 71 | When \code{gapwidth=0} and \code{from=1} (the defaults), the returned 72 | IRanges can be seen as a partitioning of the 1:sum(width) interval. 73 | See \code{?Partitioning} for more details on this. 74 | 75 | \code{breakInChunks} returns a \link{PartitioningByEnd} object 76 | describing the "chunks" that result from breaking a vector-like object 77 | of length \code{totalsize} in the chunks described by \code{nchunk} or 78 | \code{chunksize}. 79 | 80 | \code{whichAsIRanges} returns an \link{IRanges} instance containing all of 81 | the ranges where \code{x} is \code{TRUE}. 82 | 83 | If \code{force=TRUE} (the default), then \code{asNormalIRanges} will 84 | turn \code{x} into a \link{NormalIRanges} instance by reordering and 85 | reducing the set of ranges if necessary (i.e. only if \code{isNormal(x)} 86 | is \code{FALSE}, otherwise the set of ranges will be untouched). 87 | If \code{force=FALSE}, then \code{asNormalIRanges} will turn \code{x} 88 | into a \link{NormalIRanges} instance only if \code{isNormal(x)} is 89 | \code{TRUE}, otherwise it will raise an error. 90 | Note that when \code{force=FALSE}, the returned object is guaranteed 91 | to contain exactly the same set of ranges than \code{x}. 92 | \code{as(x, "NormalIRanges")} is equivalent to \code{asNormalIRanges(x, force=TRUE)}. 93 | } 94 | 95 | \author{Hervé Pagès} 96 | 97 | \seealso{ 98 | \itemize{ 99 | \item \link{IRanges} objects. 100 | 101 | \item \link{Partitioning} objects. 102 | 103 | \item \code{\link{equisplit}} for splitting a list-like object into 104 | a specified number of partitions. 105 | 106 | \item \link{intra-range-methods} and \link{inter-range-methods} 107 | for intra range and inter range transformations. 108 | 109 | \item \link{setops-methods} for performing set operations on 110 | \link{IRanges} objects. 111 | 112 | \item \code{\link{solveUserSEW}} 113 | 114 | \item \code{\link{successiveViews}} 115 | } 116 | } 117 | 118 | \examples{ 119 | vec <- as.integer(c(19, 5, 0, 8, 5)) 120 | 121 | successiveIRanges(vec) 122 | 123 | breakInChunks(600999, chunksize=50000) # chunks of size 50000 (last 124 | # chunk is smaller) 125 | 126 | whichAsIRanges(vec >= 5) 127 | 128 | x <- IRanges(start=c(-2L, 6L, 9L, -4L, 1L, 0L, -6L, 10L), 129 | width=c( 5L, 0L, 6L, 1L, 4L, 3L, 2L, 3L)) 130 | asNormalIRanges(x) # 3 non-empty ranges ordered from left to right and 131 | # separated by gaps of width >= 1. 132 | 133 | ## More on normality: 134 | example(`IRanges-class`) 135 | isNormal(x16) # FALSE 136 | if (interactive()) 137 | x16 <- asNormalIRanges(x16) # Error! 138 | whichFirstNotNormal(x16) # 57 139 | isNormal(x16[1:56]) # TRUE 140 | xx <- asNormalIRanges(x16[1:56]) 141 | class(xx) 142 | max(xx) 143 | min(xx) 144 | } 145 | 146 | \keyword{utilities} 147 | -------------------------------------------------------------------------------- /man/IntegerRanges-class.Rd: -------------------------------------------------------------------------------- 1 | \name{IntegerRanges-class} 2 | \docType{class} 3 | 4 | % Classes: 5 | \alias{class:IntegerRanges} 6 | \alias{IntegerRanges-class} 7 | \alias{IntegerRanges} 8 | 9 | \title{IntegerRanges objects} 10 | 11 | \description{ 12 | The IntegerRanges \emph{virtual} class is a general container for storing 13 | ranges on the space of integers. 14 | } 15 | 16 | \details{ 17 | TODO 18 | } 19 | 20 | \keyword{methods} 21 | \keyword{classes} 22 | -------------------------------------------------------------------------------- /man/RangedSelection-class.Rd: -------------------------------------------------------------------------------- 1 | \name{RangedSelection-class} 2 | \docType{class} 3 | \alias{RangedSelection-class} 4 | 5 | % accessors 6 | \alias{ranges,RangedSelection-method} 7 | \alias{colnames,RangedSelection-method} 8 | \alias{ranges<-,RangedSelection-method} 9 | \alias{colnames<-,RangedSelection-method} 10 | 11 | % coercion 12 | \alias{coerce,IntegerRangesList,RangedSelection-method} 13 | 14 | % constructor 15 | \alias{RangedSelection} 16 | 17 | \title{Selection of ranges and columns} 18 | 19 | \description{A \code{RangedSelection} represents a query against a table 20 | of interval data in terms of ranges and column names. The ranges 21 | select any table row with an overlapping interval. Note that the 22 | intervals are always returned, even if no columns are selected.} 23 | 24 | \details{ 25 | Traditionally, tabular data structures have supported the 26 | \code{\link{subset}} function, which allows one to select a subset of 27 | the rows and columns from the table. In that case, the rows and 28 | columns are specified by two separate arguments. As querying interval 29 | data sources, especially those external to R, such as binary indexed 30 | files and databases, is increasingly common, there is a need to 31 | encapsulate the row and column specifications into a single data 32 | structure, mostly for the sake of interface 33 | cleanliness. The \code{RangedSelection} class fills that role. 34 | } 35 | 36 | \section{Constructor}{ 37 | \describe{ 38 | \item{\code{RangedSelection(ranges=IRangesList(), 39 | colnames = character())}:}{ Constructors a \code{RangedSelection} 40 | with the given \code{ranges} and \code{colnames}. 41 | } 42 | } 43 | } 44 | 45 | \section{Coercion}{ 46 | \describe{ 47 | \item{\code{as(from, "RangedSelection")}:}{ Coerces \code{from} to a 48 | \code{RangedSelection} object. Typically, \code{from} is a 49 | \code{\linkS4class{IntegerRangesList}}, the ranges of which become the 50 | ranges in the new \code{RangedSelection}. 51 | } 52 | } 53 | } 54 | 55 | \section{Accessors}{ 56 | In the code snippets below, \code{x} is always a \code{RangedSelection}. 57 | \describe{ 58 | \item{\code{ranges(x), ranges(x) <- value}:}{ Gets or sets the 59 | ranges, a \code{\linkS4class{IntegerRangesList}}, that select rows with 60 | overlapping intervals. 61 | } 62 | \item{\code{colnames(x), colnames(x) <- value}:}{ Gets the 63 | names, a \code{character} vector, indicating the columns. 64 | } 65 | } 66 | } 67 | 68 | \author{ Michael Lawrence } 69 | 70 | \examples{ 71 | rl <- IRangesList(chr1 = IRanges(c(1, 5), c(3, 6))) 72 | 73 | RangedSelection(rl) 74 | as(rl, "RangedSelection") # same as above 75 | 76 | RangedSelection(rl, "score") 77 | } 78 | 79 | \keyword{methods} 80 | \keyword{classes} 81 | -------------------------------------------------------------------------------- /man/Rle-class-leftovers.Rd: -------------------------------------------------------------------------------- 1 | \name{Rle-class-leftovers} 2 | \docType{class} 3 | 4 | \alias{ranges,Rle-method} 5 | 6 | \alias{coerce,Rle,IRanges-method} 7 | \alias{coerce,Rle,NormalIRanges-method} 8 | 9 | \alias{findRange} 10 | \alias{findRange,Rle-method} 11 | 12 | \alias{splitRanges} 13 | \alias{splitRanges,Rle-method} 14 | \alias{splitRanges,vector_OR_factor-method} 15 | 16 | 17 | \title{Rle objects (old man page)} 18 | 19 | \description{ 20 | IMPORTANT NOTE - 7/3/2014: This man page is being refactored. Most of 21 | the things that used to be documented here have been moved to the man 22 | page for \link[S4Vectors]{Rle} objects located in the \pkg{S4Vectors} 23 | package. 24 | } 25 | 26 | \section{Coercion}{ 27 | In the code snippets below, \code{from} is an Rle object: 28 | \describe{ 29 | \item{\code{as(from, "IRanges")}:}{ Creates an \link{IRanges} instance 30 | from a logical Rle. Note that this instance is guaranteed to be normal. 31 | } 32 | \item{\code{as(from, "NormalIRanges")}:}{ Creates a \link{NormalIRanges} instance 33 | from a logical Rle. 34 | } 35 | } 36 | } 37 | 38 | \section{General Methods}{ 39 | In the code snippets below, \code{x} is an Rle object: 40 | 41 | \describe{ 42 | \item{\code{split(x, f, drop=FALSE)}:}{ 43 | Splits \code{x} according to \code{f} to create a 44 | \link{CompressedRleList} object. 45 | If \code{f} is a list-like object then \code{drop} is ignored 46 | and \code{f} is treated as if it was 47 | \code{rep(seq_len(length(f)), sapply(f, length))}, 48 | so the returned object has the same shape as \code{f} (it also 49 | receives the names of \code{f}). 50 | Otherwise, if \code{f} is not a list-like object, empty list 51 | elements are removed from the returned object if \code{drop} is 52 | \code{TRUE}. 53 | } 54 | \item{\code{findRange(x, vec)}:}{ 55 | Returns an \link{IRanges} object representing the ranges in Rle \code{vec} 56 | that are referenced by the indices in the integer vector \code{x}. 57 | } 58 | \item{\code{splitRanges(x)}:}{ 59 | Returns a \linkS4class{CompressedIRangesList} object that contains the 60 | ranges for each of the unique run values. 61 | } 62 | } 63 | } 64 | 65 | \seealso{ 66 | The \link[S4Vectors]{Rle} class defined and documented in the 67 | \pkg{S4Vectors} package. 68 | } 69 | 70 | \examples{ 71 | x <- Rle(10:1, 1:10) 72 | x 73 | } 74 | 75 | \keyword{methods} 76 | \keyword{classes} 77 | -------------------------------------------------------------------------------- /man/RleViews-class.Rd: -------------------------------------------------------------------------------- 1 | \name{RleViews-class} 2 | \docType{class} 3 | 4 | % Classes: 5 | \alias{class:RleViews} 6 | \alias{RleViews-class} 7 | \alias{RleViews} 8 | 9 | % Constructors: 10 | \alias{Views,Rle-method} 11 | 12 | % Methods: 13 | \alias{show,RleViews-method} 14 | 15 | \title{The RleViews class} 16 | 17 | \description{ 18 | The RleViews class is the basic container for storing a set of views 19 | (start/end locations) on the same Rle object. 20 | } 21 | 22 | \details{ 23 | An RleViews object contains a set of views (start/end locations) on the same 24 | \link{Rle} object called "the subject vector" or simply "the subject". 25 | Each view is defined by its start and end locations: both are integers such 26 | that start <= end. 27 | An RleViews object is in fact a particular case of a \link{Views} 28 | object (the RleViews class contains the \link{Views} class) so it 29 | can be manipulated in a similar manner: see \code{?\link{Views}} for 30 | more information. 31 | Note that two views can overlap and that a view can be "out of limits" 32 | i.e. it can start before the first element of the subject or/and end 33 | after its last element. 34 | } 35 | 36 | \author{P. Aboyoun} 37 | 38 | \seealso{ 39 | \link{Views-class}, 40 | \link{Rle-class}, 41 | \link{view-summarization-methods} 42 | } 43 | 44 | \examples{ 45 | subject <- Rle(rep(c(3L, 2L, 18L, 0L), c(3,2,1,5))) 46 | myViews <- Views(subject, 3:0, 5:8) 47 | myViews 48 | subject(myViews) 49 | length(myViews) 50 | start(myViews) 51 | end(myViews) 52 | width(myViews) 53 | myViews[[2]] 54 | 55 | set.seed(0) 56 | vec <- Rle(sample(0:2, 20, replace = TRUE)) 57 | vec 58 | Views(vec, vec > 0) 59 | } 60 | 61 | \keyword{methods} 62 | \keyword{classes} 63 | -------------------------------------------------------------------------------- /man/RleViewsList-class.Rd: -------------------------------------------------------------------------------- 1 | \name{RleViewsList-class} 2 | \docType{class} 3 | \alias{RleViewsList-class} 4 | \alias{SimpleRleViewsList-class} 5 | 6 | % accessor 7 | \alias{subject,SimpleRleViewsList-method} 8 | 9 | % constructor 10 | \alias{Views,RleList-method} 11 | \alias{RleViewsList} 12 | 13 | % coercion 14 | \alias{coerce,RleViewsList,SimpleIRangesList-method} 15 | \alias{coerce,RleViewsList,IRangesList-method} 16 | 17 | \title{List of RleViews} 18 | \description{An extension of \linkS4class{ViewsList} that holds only 19 | \linkS4class{RleViews} objects. Useful for storing coverage vectors 20 | over a set of spaces (e.g. chromosomes), each of which requires a separate 21 | \linkS4class{RleViews} object. 22 | } 23 | 24 | \details{ 25 | For more information on methods available for RleViewsList objects consult 26 | the man pages for \link{ViewsList-class} and 27 | \link{view-summarization-methods}. 28 | } 29 | 30 | \section{Constructor}{ 31 | \describe{ 32 | \item{\code{RleViewsList(..., rleList, rangesList)}:}{ 33 | Either \code{...} or the \code{rleList}/\code{rangesList} couplet 34 | provide the RleViews for the list. If \code{...} is provided, each 35 | of these arguments must be RleViews objects. Alternatively, 36 | \code{rleList} and \code{rangesList} accept Rle and IntegerRanges 37 | objects respectively that are meshed together for form the RleViewsList. 38 | } 39 | \item{\code{Views(subject, start=NULL, end=NULL, width=NULL, names=NULL)}:}{ 40 | Same as \code{RleViewsList(rleList = subject, rangesList = start)}. 41 | } 42 | } 43 | } 44 | 45 | \section{Coercion}{ 46 | In the code snippet below, \code{from} is an RleViewsList object: 47 | 48 | \describe{ 49 | \item{\code{as(from, "IRangesList")}:}{ Creates an \code{IRangesList} 50 | object containing the view locations in \code{from}. 51 | } 52 | } 53 | } 54 | 55 | \author{P. Aboyoun} 56 | 57 | \seealso{ 58 | \link{ViewsList-class}, 59 | \link{view-summarization-methods} 60 | } 61 | 62 | \examples{ 63 | ## Rle objects 64 | subject1 <- Rle(c(3L,2L,18L,0L), c(3,2,1,5)) 65 | set.seed(0) 66 | subject2 <- Rle(c(0L,5L,2L,0L,3L), c(8,5,2,7,4)) 67 | 68 | ## Views 69 | rleViews1 <- Views(subject1, 3:0, 5:8) 70 | rleViews2 <- Views(subject2, subject2 > 0) 71 | 72 | ## RleList and IntegerRangesList objects 73 | rleList <- RleList(subject1, subject2) 74 | rangesList <- IRangesList(IRanges(3:0, 5:8), IRanges(subject2 > 0)) 75 | 76 | ## methods for construction 77 | method1 <- RleViewsList(rleViews1, rleViews2) 78 | method2 <- RleViewsList(rleList = rleList, rangesList = rangesList) 79 | identical(method1, method2) 80 | 81 | ## calculation over the views 82 | viewSums(method1) 83 | } 84 | 85 | \keyword{methods} 86 | \keyword{classes} 87 | -------------------------------------------------------------------------------- /man/Vector-class-leftovers.Rd: -------------------------------------------------------------------------------- 1 | \name{Vector-class-leftovers} 2 | \docType{class} 3 | 4 | \alias{window<-,Vector-method} 5 | \alias{window<-.Vector} 6 | \alias{window<-,vector-method} 7 | \alias{window<-.vector} 8 | \alias{window<-,factor-method} 9 | \alias{window<-.factor} 10 | 11 | \alias{tapply,ANY,Vector-method} 12 | \alias{tapply,Vector,ANY-method} 13 | \alias{tapply,Vector,Vector-method} 14 | 15 | \alias{with,Vector-method} 16 | \alias{eval} 17 | \alias{eval,expression,Vector-method} 18 | \alias{eval,language,Vector-method} 19 | 20 | \title{Vector objects (old man page)} 21 | 22 | \description{ 23 | IMPORTANT NOTE - 4/29/2014: This man page is being refactored. Most of 24 | the things that used to be documented here have been moved to the man 25 | page for \link[S4Vectors]{Vector} objects located in the \pkg{S4Vectors} 26 | package. 27 | } 28 | 29 | \section{Evaluation}{ 30 | In the following code snippets, \code{x} is a Vector object. 31 | 32 | \describe{ 33 | \item{\code{with(x, expr)}:}{ Evaluates \code{expr} within 34 | \code{as.env(x)} via \code{eval(x)}. 35 | } 36 | \item{\code{eval(expr, envir, enclos=parent.frame())}:}{ Evaluates 37 | \code{expr} within \code{envir}, where \code{envir} is coerced to 38 | an environment with \code{as.env(envir, enclos)}. The \code{expr} 39 | is first processed with \code{\link{bquote}}, such that any 40 | escaped symbols are directly resolved in the calling frame. 41 | } 42 | } 43 | } 44 | 45 | \section{Convenience wrappers for common subsetting operations}{ 46 | In the code snippets below, \code{x} is a Vector object or regular R vector 47 | object. The R vector object methods for \code{window} are defined in this 48 | package and the remaining methods are defined in base R. 49 | 50 | \describe{ 51 | \item{\code{window(x, start=NA, end=NA, width=NA) <- value}:}{ 52 | Replace the subsequence window specified on the left (i.e. the 53 | subsequence in \code{x} specified by \code{start}, \code{end} and 54 | \code{width}) by \code{value}. 55 | \code{value} must either be of class \code{class(x)}, belong to a 56 | subclass of \code{class(x)}, or be coercible to \code{class(x)} or a 57 | subclass of \code{class(x)}. 58 | The elements of \code{value} are repeated to create a Vector with the 59 | same number of elements as the width of the subsequence window it is 60 | replacing. 61 | } 62 | } 63 | } 64 | 65 | \section{Looping}{ 66 | In the code snippets below, \code{x} is a Vector object. 67 | 68 | \describe{ 69 | \item{\code{tapply(X, INDEX, FUN = NULL, ..., simplify = TRUE)}:}{ 70 | Like the standard \code{\link[base]{tapply}} function defined in the 71 | base package, the \code{tapply} method for Vector objects applies a 72 | function to each cell of a ragged array, that is to each (non-empty) 73 | group of values given by a unique combination of the levels of certain 74 | factors. 75 | } 76 | } 77 | } 78 | 79 | \section{Coercion}{ 80 | \describe{ 81 | \item{\code{as.list(x)}:}{ coerce a Vector to a list, where the \code{i}th 82 | element of the result corresponds to \code{x[i]}. 83 | } 84 | } 85 | } 86 | 87 | \seealso{ 88 | The \link[S4Vectors]{Vector} class defined and documented in the 89 | \pkg{S4Vectors} package. 90 | } 91 | 92 | \keyword{methods} 93 | \keyword{classes} 94 | -------------------------------------------------------------------------------- /man/Views-class.Rd: -------------------------------------------------------------------------------- 1 | \name{Views-class} 2 | \docType{class} 3 | 4 | \alias{class:Views} 5 | \alias{Views-class} 6 | 7 | \alias{parallel_slot_names,Views-method} 8 | 9 | \alias{subject} 10 | \alias{subject,Views-method} 11 | \alias{ranges,Views-method} 12 | \alias{ranges<-} 13 | \alias{ranges<-,Views-method} 14 | \alias{start,Views-method} 15 | \alias{width,Views-method} 16 | \alias{names,Views-method} 17 | \alias{start<-,Views-method} 18 | \alias{end<-,Views-method} 19 | \alias{width<-,Views-method} 20 | \alias{names<-,Views-method} 21 | \alias{Views} 22 | \alias{unlist,Views-method} 23 | \alias{coerce,Vector,Views-method} 24 | \alias{coerce,Views,IntegerRanges-method} 25 | \alias{coerce,Views,IRanges-method} 26 | \alias{coerce,Views,NormalIRanges-method} 27 | \alias{as.matrix,Views-method} 28 | 29 | \alias{bindROWS,Views-method} 30 | 31 | \alias{trim} 32 | \alias{trim,Views-method} 33 | \alias{subviews} 34 | \alias{subviews,Views-method} 35 | \alias{successiveViews} 36 | 37 | 38 | \title{Views objects} 39 | 40 | \description{ 41 | The Views virtual class is a general container for storing a set of 42 | views on an arbitrary \link{Vector} object, called the "subject". 43 | 44 | Its primary purpose is to introduce concepts and provide some facilities 45 | that can be shared by the concrete classes that derive from it. 46 | 47 | Some direct subclasses of the Views class are: \link{RleViews}, 48 | \link[XVector]{XIntegerViews} (defined in the XVector package), 49 | \link[Biostrings]{XStringViews} (defined in the Biostrings package), 50 | etc... 51 | } 52 | 53 | \section{Constructor}{ 54 | \describe{ 55 | \item{\code{Views(subject, start=NULL, end=NULL, width=NULL, names=NULL)}:}{ 56 | This constructor is a generic function with dispatch on argument 57 | \code{subject}. Specific methods must be defined for the subclasses 58 | of the Views class. For example a method for 59 | \link[Biostrings:XString-class]{XString} subjects is defined 60 | in the Biostrings package that returns an 61 | \link[Biostrings:XStringViews-class]{XStringViews} 62 | object. There is no default method. 63 | 64 | The treatment of the \code{start}, \code{end} and \code{width} 65 | arguments is the same as with the \code{\link{IRanges}} constructor, 66 | except that, in addition, \code{Views} allows \code{start} to be an 67 | \link{IntegerRanges} object. With this feature, 68 | \code{Views(subject, IRanges(my_starts, my_ends, my_widths, my_names))} 69 | and \code{Views(subject, my_starts, my_ends, my_widths, my_names)} 70 | are equivalent (except when \code{my_starts} is itself a 71 | \link{IntegerRanges} object). 72 | } 73 | } 74 | } 75 | 76 | \section{Coercion}{ 77 | In the code snippets below, \code{from} is a Views object: 78 | 79 | \describe{ 80 | \item{\code{as(from, "IRanges")}:}{ Creates an \code{IRanges} object 81 | containing the view locations in \code{from}. 82 | } 83 | } 84 | } 85 | 86 | \section{Accessor-like methods}{ 87 | All the accessor-like methods defined for \code{IRanges} objects 88 | work on Views objects. In addition, the following accessors are defined 89 | for Views objects: 90 | 91 | \describe{ 92 | \item{\code{subject(x)}:}{ 93 | Return the subject of the views. 94 | } 95 | } 96 | } 97 | 98 | \section{Subsetting}{ 99 | \describe{ 100 | \item{\code{x[i]}:}{ Select the views specified by \code{i}. 101 | } 102 | \item{\code{x[[i]]}:}{ 103 | Extracts the view selected by \code{i} as an object of the same class 104 | as \code{subject(x)}. Subscript \code{i} can be a single integer 105 | or a character string. 106 | The result is the subsequence of \code{subject(x)} defined by 107 | \code{window(subject(x), start=start(x)[i], end=end(x)[i])} 108 | or an error if the view is "out of limits" (i.e. \code{start(x)[i] < 1} 109 | or \code{end(x)[i] > length(subject(x))}). 110 | } 111 | } 112 | } 113 | 114 | \section{Concatenation}{ 115 | \describe{ 116 | \item{\code{c(x, ..., ignore.mcols=FALSE)}:}{ Concatenate \code{Views} objects. 117 | They must have the same subject. 118 | } 119 | } 120 | } 121 | 122 | \section{Other methods}{ 123 | \describe{ 124 | \item{\code{trim(x, use.names=TRUE)}:}{ 125 | Equivalent to 126 | \code{restrict(x, start=1L, end=length(subject(x)), keep.all.ranges=TRUE, 127 | use.names=use.names)}. 128 | } 129 | \item{\code{subviews(x, start=NA, end=NA, width=NA, use.names=TRUE)}:}{ 130 | \code{start}, \code{end}, and \code{width} arguments must be vectors 131 | of integers, eventually with NAs, that contain coordinates relative 132 | to the current ranges. Equivalent to 133 | \code{trim(narrow(x, start=start, end=end, width=width, use.names=use.names))}. 134 | } 135 | \item{\code{successiveViews(subject, width, gapwidth=0, from=1)}:}{ 136 | Equivalent to \code{Views(subject, successiveIRanges(width, gapwidth, from))}. 137 | See \code{?successiveIRanges} for a description of the \code{width}, 138 | \code{gapwidth} and \code{from} arguments. 139 | } 140 | } 141 | } 142 | 143 | \author{Hervé Pagès} 144 | 145 | \seealso{ 146 | \link{IRanges-class}, 147 | \link{Vector-class}, 148 | \link{IRanges-utils}, 149 | \link[XVector]{XVector}. 150 | 151 | Some direct subclasses of the Views class: 152 | \link{RleViews-class}, 153 | \link[XVector]{XIntegerViews-class}, 154 | \link[XVector]{XDoubleViews-class}, 155 | \link[Biostrings]{XStringViews-class}. 156 | 157 | \code{\link{findOverlaps}}. 158 | } 159 | 160 | \examples{ 161 | showClass("Views") # shows (some of) the known subclasses 162 | 163 | ## Create a set of 4 views on an XInteger subject of length 10: 164 | subject <- Rle(3:-6) 165 | v1 <- Views(subject, start=4:1, end=4:7) 166 | 167 | ## Extract the 2nd view: 168 | v1[[2]] 169 | 170 | ## Some views can be "out of limits" 171 | v2 <- Views(subject, start=4:-1, end=6) 172 | trim(v2) 173 | subviews(v2, end=-2) 174 | 175 | ## See ?`XIntegerViews-class` in the XVector package for more examples. 176 | } 177 | 178 | \keyword{methods} 179 | \keyword{classes} 180 | -------------------------------------------------------------------------------- /man/ViewsList-class.Rd: -------------------------------------------------------------------------------- 1 | \name{ViewsList-class} 2 | \docType{class} 3 | \alias{class:ViewsList} 4 | \alias{ViewsList-class} 5 | \alias{ViewsList} 6 | \alias{class:SimpleViewsList} 7 | \alias{SimpleViewsList-class} 8 | \alias{SimpleViewsList} 9 | 10 | % accessors 11 | \alias{ranges,SimpleViewsList-method} 12 | \alias{start,SimpleViewsList-method} 13 | \alias{end,SimpleViewsList-method} 14 | \alias{width,SimpleViewsList-method} 15 | 16 | % coercion 17 | \alias{as.matrix,ViewsList-method} 18 | 19 | \title{List of Views} 20 | \description{An extension of \linkS4class{List} that holds only 21 | \linkS4class{Views} objects. 22 | } 23 | 24 | \details{ 25 | ViewsList is a virtual class. 26 | Specialized subclasses like e.g. \linkS4class{RleViewsList} are useful 27 | for storing coverage vectors over a set of spaces (e.g. chromosomes), 28 | each of which requires a separate \linkS4class{RleViews} object. 29 | 30 | As a \linkS4class{List} subclass, ViewsList inherits all the methods 31 | available for \linkS4class{List} objects. It also presents an API that 32 | is very similar to that of \linkS4class{Views}, where operations are 33 | vectorized over the elements and generally return lists. 34 | } 35 | 36 | \author{P. Aboyoun and H. Pagès} 37 | 38 | \seealso{ 39 | \link{List-class}, 40 | \link{RleViewsList-class}. 41 | 42 | \code{\link{findOverlaps}}. 43 | } 44 | 45 | \examples{ 46 | showClass("ViewsList") 47 | } 48 | 49 | \keyword{methods} 50 | \keyword{classes} 51 | -------------------------------------------------------------------------------- /man/extractList.Rd: -------------------------------------------------------------------------------- 1 | \name{extractList} 2 | 3 | \alias{relist} 4 | \alias{relist,ANY,PartitioningByEnd-method} 5 | \alias{relist,ANY,List-method} 6 | \alias{relist,Vector,list-method} 7 | 8 | \alias{extractList} 9 | \alias{extractList,ANY,ANY-method} 10 | \alias{extractList,ANY-method} 11 | 12 | \alias{regroup} 13 | 14 | \title{Group elements of a vector-like object into a list-like object} 15 | 16 | \description{ 17 | \code{relist} and \code{split} are 2 common ways of grouping the elements 18 | of a vector-like object into a list-like object. The \pkg{IRanges} and 19 | \pkg{S4Vectors} packages define \code{relist} and \code{split} methods 20 | that operate on a \link{Vector} object and return a \link{List} object. 21 | 22 | Because \code{relist} and \code{split} both impose restrictions on 23 | the kind of grouping that they support (e.g. every element in the input 24 | object needs to go in a group and can only go in one group), the 25 | \pkg{IRanges} package introduces the \code{extractList} generic function 26 | for performing \emph{arbitrary} groupings. 27 | } 28 | 29 | \usage{ 30 | ## relist() 31 | ## -------- 32 | 33 | \S4method{relist}{ANY,List}(flesh, skeleton) 34 | 35 | \S4method{relist}{Vector,list}(flesh, skeleton) 36 | 37 | ## extractList() 38 | ## ------------- 39 | 40 | extractList(x, i) 41 | 42 | ## regroup() 43 | ## --------- 44 | 45 | regroup(x, g) 46 | } 47 | 48 | \arguments{ 49 | \item{flesh, x}{ 50 | A vector-like object. 51 | } 52 | \item{skeleton}{ 53 | A list-like object. Only the "shape" (i.e. element lengths) of 54 | \code{skeleton} matters. Its exact content is ignored. 55 | } 56 | \item{i}{ 57 | A list-like object. Unlike for \code{skeleton}, the content here matters 58 | (see Details section below). 59 | Note that \code{i} can be a \link{IntegerRanges} object (a particular 60 | type of list-like object), and, in that case, \code{extractList} is 61 | particularly fast (this is a common use case). 62 | } 63 | \item{g}{ 64 | A \linkS4class{Grouping} or an object coercible to one. For 65 | \code{regroup}, \code{g} groups the elements of \code{x}. 66 | } 67 | } 68 | 69 | \details{ 70 | Like \code{split}, \code{relist} and \code{extractList} have in common 71 | that they return a list-like object where all the list elements have the 72 | same class as the original vector-like object. 73 | 74 | Methods that return a \link{List} derivative return an object of class 75 | \code{\link[S4Vectors]{relistToClass}(x)}. 76 | 77 | By default, \code{extractList(x, i)} is equivalent to: 78 | \preformatted{ relist(x[unlist(i)], i) 79 | } 80 | An exception is made when \code{x} is a data-frame-like object. In that 81 | case \code{x} is subsetted along the rows, that is, \code{extractList(x, i)} 82 | is equivalent to: 83 | \preformatted{ relist(x[unlist(i), ], i) 84 | } 85 | This is more or less how the default method is implemented, except for 86 | some optimizations when \code{i} is a \link{IntegerRanges} object. 87 | 88 | \code{relist} and \code{split} can be seen as special cases of 89 | \code{extractList}: 90 | \preformatted{ relist(flesh, skeleton) is equivalent to 91 | extractList(flesh, PartitioningByEnd(skeleton)) 92 | 93 | split(x, f) is equivalent to 94 | extractList(x, split(seq_along(f), f)) 95 | } 96 | It is good practise to use \code{extractList} only for cases not covered 97 | by \code{relist} or \code{split}. Whenever possible, using \code{relist} 98 | or \code{split} is preferred as they will always perform more efficiently. 99 | In addition their names carry meaning and are familiar to most R 100 | users/developers so they'll make your code easier to read/understand. 101 | 102 | Note that the transformation performed by \code{relist} or \code{split} 103 | is always reversible (via \code{unlist} and \code{unsplit}, respectively), 104 | but not the transformation performed by \code{extractList} (in general). 105 | 106 | The \code{regroup} function splits the elements of \code{unlist(x)} 107 | into a list according to the grouping \code{g}. Each element of 108 | \code{unlist(x)} inherits its group from its parent element of 109 | \code{x}. \code{regroup} is different from \code{relist} and 110 | \code{split}, because \code{x} is already grouped, and the goal is to 111 | combine groups. 112 | 113 | } 114 | 115 | \value{ 116 | The \code{relist} methods behave like \code{utils::relist} except that they 117 | return a \link{List} object. If \code{skeleton} has names, then they are 118 | propagated to the returned value. 119 | 120 | \code{extractList} returns a list-like object parallel to \code{i} and with 121 | the same "shape" as \code{i} (i.e. same element lengths). 122 | If \code{i} has names, then they are propagated to the returned value. 123 | 124 | All these functions return a list-like object where the list elements have 125 | the same class as \code{x}. \code{\link[S4Vectors]{relistToClass}} gives 126 | the exact class of the returned object. 127 | } 128 | 129 | \author{Hervé Pagès} 130 | 131 | \seealso{ 132 | \itemize{ 133 | \item The \code{\link[S4Vectors]{relistToClass}} function and 134 | \code{\link[S4Vectors]{split}} methods defined in the 135 | \pkg{S4Vectors} package. 136 | 137 | \item The \code{\link[base]{unlist}} and \code{\link[utils]{relist}} 138 | functions in the \pkg{base} and \pkg{utils} packages, respectively. 139 | 140 | \item The \code{\link[base]{split}} and \code{\link[base]{unsplit}} 141 | functions in the \pkg{base} package. 142 | 143 | \item \link{PartitioningByEnd} objects. These objects are used inside 144 | \link{CompressedList} derivatives to keep track of the 145 | \emph{partitioning} of the single vector-like object made of 146 | all the list elements concatenated together. 147 | 148 | \item \link[S4Vectors]{Vector}, \link[S4Vectors]{List}, 149 | \link[S4Vectors]{Rle}, and \link[S4Vectors]{DataFrame} objects 150 | implemented in the \pkg{S4Vectors} package. 151 | 152 | \item \link{IntegerRanges} objects. 153 | } 154 | } 155 | 156 | \examples{ 157 | ## On an Rle object: 158 | x <- Rle(101:105, 6:2) 159 | i <- IRanges(6:10, 16:12, names=letters[1:5]) 160 | extractList(x, i) 161 | 162 | ## On a DataFrame object: 163 | df <- DataFrame(X=x, Y=LETTERS[1:20]) 164 | extractList(df, i) 165 | } 166 | 167 | \keyword{manip} 168 | -------------------------------------------------------------------------------- /man/multisplit.Rd: -------------------------------------------------------------------------------- 1 | \name{multisplit} 2 | \alias{multisplit} 3 | 4 | \title{ 5 | Split elements belonging to multiple groups 6 | } 7 | 8 | \description{ 9 | This is like \code{\link{split}}, except elements can belong to 10 | multiple groups, in which case they are repeated to appear in multiple 11 | elements of the return value. 12 | } 13 | 14 | \usage{ 15 | multisplit(x, f) 16 | } 17 | 18 | \arguments{ 19 | \item{x}{ 20 | The object to split, like a vector. 21 | } 22 | \item{f}{ 23 | A list-like object of vectors, the same length as \code{x}, where 24 | each element indicates the groups to which each element of \code{x} 25 | belongs. 26 | } 27 | } 28 | 29 | \value{ 30 | A list-like object, with an element for each unique value in the 31 | unlisted \code{f}, containing the elements in \code{x} where the 32 | corresponding element in \code{f} contained that value. Just try it. 33 | } 34 | 35 | \author{ 36 | Michael Lawrence 37 | } 38 | 39 | \examples{ 40 | multisplit(1:3, list(letters[1:2], letters[2:3], letters[2:4])) 41 | } 42 | 43 | \keyword{ manip } 44 | -------------------------------------------------------------------------------- /man/range-squeezers.Rd: -------------------------------------------------------------------------------- 1 | \name{range-squeezers} 2 | 3 | \alias{range-squeezers} 4 | 5 | \alias{ranges} 6 | \alias{rglist} 7 | 8 | \alias{rglist,Pairs-method} 9 | 10 | \title{Squeeze the ranges out of a range-based object} 11 | 12 | \description{ 13 | S4 generic functions for squeezing the ranges out of a range-based object. 14 | 15 | These are analog to range squeezers \code{\link[GenomicRanges]{granges}} 16 | and \code{\link[GenomicRanges]{grglist}} defined in the \pkg{GenomicRanges} 17 | package, except that \code{ranges} returns the ranges in an \link{IRanges} 18 | object (instead of a \link[GenomicRanges]{GRanges} object for 19 | \code{\link[GenomicRanges]{granges}}), and \code{rglist} returns them in an 20 | \link{IRangesList} object (instead of a \link[GenomicRanges]{GRangesList} 21 | object for \code{\link[GenomicRanges]{grglist}}). 22 | } 23 | 24 | \usage{ 25 | ranges(x, use.names=TRUE, use.mcols=FALSE, ...) 26 | rglist(x, use.names=TRUE, use.mcols=FALSE, ...) 27 | } 28 | 29 | \arguments{ 30 | \item{x}{ 31 | An object containing ranges e.g. a 32 | \link{IntegerRanges}, \link[GenomicRanges]{GenomicRanges}, 33 | \link[SummarizedExperiment]{RangedSummarizedExperiment}, 34 | \link[GenomicAlignments]{GAlignments}, 35 | \link[GenomicAlignments]{GAlignmentPairs}, or 36 | \link[GenomicAlignments]{GAlignmentsList} object, 37 | or a \link[S4Vectors]{Pairs} object containing ranges. 38 | } 39 | \item{use.names}{ 40 | \code{TRUE} (the default) or \code{FALSE}. 41 | Whether or not the names on \code{x} (accessible with \code{names(x)}) 42 | should be propagated to the returned object. 43 | } 44 | \item{use.mcols}{ 45 | \code{TRUE} or \code{FALSE} (the default). 46 | Whether or not the metadata columns on \code{x} (accessible with 47 | \code{mcols(x)}) should be propagated to the returned object. 48 | } 49 | \item{...}{ 50 | Additional arguments, for use in specific methods. 51 | } 52 | } 53 | 54 | \details{ 55 | Various packages (e.g. \pkg{IRanges}, \pkg{GenomicRanges}, 56 | \pkg{SummarizedExperiment}, \pkg{GenomicAlignments}, etc...) 57 | define and document various range squeezing methods for various types 58 | of objects. 59 | 60 | Note that these functions can be seen as \emph{object getters} or as 61 | functions performing coercion. 62 | 63 | For some objects (e.g. \link[GenomicAlignments]{GAlignments} and 64 | \link[GenomicAlignments]{GAlignmentPairs} objects defined in the 65 | \pkg{GenomicAlignments} package), \code{as(x, "IRanges")} and 66 | \code{as(x, "IRangesList")}, are equivalent to 67 | \code{ranges(x, use.names=TRUE, use.mcols=TRUE)} and 68 | \code{rglist(x, use.names=TRUE, use.mcols=TRUE)}, respectively. 69 | } 70 | 71 | \value{ 72 | An \link{IRanges} object for \code{ranges}. 73 | 74 | An \link{IRangesList} object for \code{rglist}. 75 | 76 | If \code{x} is a vector-like object (e.g. 77 | \link[GenomicAlignments]{GAlignments}), the returned object is expected 78 | to be \emph{parallel} to \code{x}, that is, the i-th element in the output 79 | corresponds to the i-th element in the input. 80 | 81 | If \code{use.names} is TRUE, then the names on \code{x} 82 | (if any) are propagated to the returned object. 83 | If \code{use.mcols} is TRUE, then the metadata columns on \code{x} 84 | (if any) are propagated to the returned object. 85 | } 86 | 87 | \author{H. Pagès} 88 | 89 | \seealso{ 90 | \itemize{ 91 | \item \link{IRanges} and \link{IRangesList} objects. 92 | 93 | \item \link[SummarizedExperiment]{RangedSummarizedExperiment} objects 94 | in the \pkg{SummarizedExperiment} packages. 95 | 96 | \item \link[GenomicAlignments]{GAlignments}, 97 | \link[GenomicAlignments]{GAlignmentPairs}, 98 | and \link[GenomicAlignments]{GAlignmentsList} objects in the 99 | \pkg{GenomicAlignments} package. 100 | } 101 | } 102 | 103 | \examples{ 104 | ## See ?GAlignments in the GenomicAlignments package for examples of 105 | ## "ranges" and "rglist" methods. 106 | } 107 | 108 | \keyword{methods} 109 | -------------------------------------------------------------------------------- /man/reverse-methods.Rd: -------------------------------------------------------------------------------- 1 | \name{reverse} 2 | 3 | \alias{reverse} 4 | \alias{reverse,character-method} 5 | \alias{reverse,IRanges-method} 6 | \alias{reverse,NormalIRanges-method} 7 | \alias{reverse,Views-method} 8 | \alias{reverse,MaskCollection-method} 9 | 10 | 11 | \title{reverse} 12 | 13 | \description{ 14 | A generic function for reversing vector-like or list-like objects. 15 | This man page describes methods for reversing a character vector, 16 | a \link{Views} object, or a \link{MaskCollection} object. 17 | Note that \code{reverse} is similar to but not the same as 18 | \code{\link[base]{rev}}. 19 | } 20 | 21 | \usage{ 22 | reverse(x, ...) 23 | } 24 | 25 | \arguments{ 26 | \item{x}{ 27 | A vector-like or list-like object. 28 | } 29 | \item{...}{ 30 | Additional arguments to be passed to or from methods. 31 | } 32 | } 33 | 34 | \details{ 35 | On a character vector or a \link{Views} object, \code{reverse} reverses 36 | each element individually, without modifying the top-level order of the 37 | elements. More precisely, each individual string of a character vector 38 | is reversed. 39 | } 40 | 41 | \value{ 42 | An object of the same class and length as the original object. 43 | } 44 | 45 | \seealso{ 46 | \itemize{ 47 | \item \code{\link[base]{rev}} in base R. 48 | 49 | \item \code{\link{revElements}} in the \pkg{S4Vectors} package to 50 | reverse all or some of the list elements of a list-like object. 51 | 52 | \item \link{Views} objects. 53 | 54 | \item \link{MaskCollection} objects. 55 | 56 | \item \link[XVector]{reverse-methods} in the \pkg{XVector} package. 57 | } 58 | } 59 | 60 | \examples{ 61 | ## On a character vector: 62 | reverse(c("Hi!", "How are you?")) 63 | rev(c("Hi!", "How are you?")) 64 | 65 | ## On a Views object: 66 | v <- successiveViews(Rle(c(-0.5, 12.3, 4.88), 4:2), 1:4) 67 | v 68 | reverse(v) 69 | rev(v) 70 | 71 | ## On a MaskCollection object: 72 | mask1 <- Mask(mask.width=29, start=c(11, 25, 28), width=c(5, 2, 2)) 73 | mask2 <- Mask(mask.width=29, start=c(3, 10, 27), width=c(5, 8, 1)) 74 | mask3 <- Mask(mask.width=29, start=c(7, 12), width=c(2, 4)) 75 | mymasks <- append(append(mask1, mask2), mask3) 76 | reverse(mymasks) 77 | } 78 | 79 | \keyword{methods} 80 | \keyword{manip} 81 | -------------------------------------------------------------------------------- /man/seqapply.Rd: -------------------------------------------------------------------------------- 1 | \name{seqapply} 2 | 3 | \alias{unsplit,List-method} 4 | \alias{split<-,Vector-method} 5 | 6 | \title{ 7 | 2 methods that should be documented somewhere else 8 | } 9 | \description{ 10 | \code{unsplit} method for \link{List} object and \code{split<-} 11 | method for \link{Vector} object. 12 | } 13 | 14 | \usage{ 15 | \S4method{unsplit}{List}(value, f, drop = FALSE) 16 | \S4method{split}{Vector}(x, f, drop = FALSE, ...) <- value 17 | } 18 | 19 | \arguments{ 20 | \item{value}{ 21 | The \link{List} object to unsplit. 22 | } 23 | \item{f}{ 24 | A \code{factor} or \code{list} of factors 25 | } 26 | \item{drop}{ 27 | Whether to drop empty elements from the returned list 28 | } 29 | \item{x}{ 30 | Like \code{X} 31 | } 32 | \item{\dots}{ 33 | Extra arguments to pass to \code{FUN} 34 | } 35 | } 36 | 37 | \details{ 38 | \code{unsplit} unlists \code{value}, where the order of the returned 39 | vector is as if \code{value} were originally created by splitting that 40 | vector on the factor \code{f}. 41 | 42 | \code{split(x, f, drop = FALSE) <- value}: Virtually splits \code{x} by 43 | the factor \code{f}, replaces the elements of the resulting list with the 44 | elements from the list \code{value}, and restores \code{x} to its original 45 | form. Note that this works for any \code{Vector}, even though \code{split} 46 | itself is not universally supported. 47 | } 48 | 49 | \author{ 50 | Michael Lawrence 51 | } 52 | 53 | \keyword{manip} 54 | -------------------------------------------------------------------------------- /man/slice-methods.Rd: -------------------------------------------------------------------------------- 1 | \name{slice-methods} 2 | 3 | \alias{slice-methods} 4 | 5 | \alias{slice} 6 | \alias{slice,ANY-method} 7 | \alias{slice,Rle-method} 8 | \alias{slice,RleList-method} 9 | 10 | 11 | \title{Slice a vector-like or list-like object} 12 | 13 | \description{ 14 | \code{slice} is a generic function that creates views on a vector-like 15 | or list-like object that contain the elements that are within the 16 | specified bounds. 17 | } 18 | 19 | \usage{ 20 | slice(x, lower=-Inf, upper=Inf, ...) 21 | 22 | \S4method{slice}{Rle}(x, lower=-Inf, upper=Inf, 23 | includeLower=TRUE, includeUpper=TRUE, rangesOnly=FALSE) 24 | 25 | \S4method{slice}{RleList}(x, lower=-Inf, upper=Inf, 26 | includeLower=TRUE, includeUpper=TRUE, rangesOnly=FALSE) 27 | } 28 | 29 | \arguments{ 30 | \item{x}{ 31 | An \link{Rle} or \link{RleList} object, or any object coercible to 32 | an Rle object. 33 | } 34 | \item{lower, upper}{ 35 | The lower and upper bounds for the slice. 36 | } 37 | \item{includeLower, includeUpper}{ 38 | Logical indicating whether or not the specified boundary is open or closed. 39 | } 40 | \item{rangesOnly}{ 41 | A logical indicating whether or not to drop the original data from the 42 | output. 43 | } 44 | \item{...}{ 45 | Additional arguments to be passed to specific methods. 46 | } 47 | } 48 | 49 | \details{ 50 | \code{slice} is useful for finding areas of absolute maxima (peaks), 51 | absolute minima (troughs), or fluctuations within specified limits. 52 | One or more view summarization methods can be used on the result of 53 | \code{slice}. See \code{?`link{view-summarization-methods}`} 54 | } 55 | 56 | \value{ 57 | The method for \link{Rle} objects returns an \link{RleViews} object 58 | if \code{rangesOnly=FALSE} or an \link{IRanges} object if 59 | \code{rangesOnly=TRUE}. 60 | 61 | The method for \link{RleList} objects returns an \link{RleViewsList} object 62 | if \code{rangesOnly=FALSE} or an \link{IRangesList} object if 63 | \code{rangesOnly=TRUE}. 64 | } 65 | 66 | \author{P. Aboyoun} 67 | 68 | \seealso{ 69 | \itemize{ 70 | \item \link{view-summarization-methods} for summarizing the views 71 | returned by \code{slice}. 72 | 73 | \item \link[XVector]{slice-methods} in the \pkg{XVector} package 74 | for more \code{slice} methods. 75 | 76 | \item \code{\link{coverage}} for computing the coverage across a set 77 | of ranges. 78 | 79 | \item The \link{Rle}, \link{RleList}, \link{RleViews}, and 80 | \link{RleViewsList} classes. 81 | } 82 | } 83 | 84 | \examples{ 85 | ## Views derived from coverage 86 | x <- IRanges(start=c(1L, 9L, 4L, 1L, 5L, 10L), 87 | width=c(5L, 6L, 3L, 4L, 3L, 3L)) 88 | cvg <- coverage(x) 89 | slice(cvg, lower=2) 90 | slice(cvg, lower=2, rangesOnly=TRUE) 91 | } 92 | 93 | \keyword{methods} 94 | -------------------------------------------------------------------------------- /man/view-summarization-methods.Rd: -------------------------------------------------------------------------------- 1 | \name{view-summarization-methods} 2 | 3 | \alias{view-summarization-methods} 4 | 5 | \alias{viewApply} 6 | \alias{viewApply,Views-method} 7 | \alias{viewApply,RleViews-method} 8 | \alias{viewApply,RleViewsList-method} 9 | \alias{viewMins} 10 | \alias{viewMins,RleViews-method} 11 | \alias{viewMins,RleViewsList-method} 12 | \alias{viewMaxs} 13 | \alias{viewMaxs,RleViews-method} 14 | \alias{viewMaxs,RleViewsList-method} 15 | \alias{viewSums} 16 | \alias{viewSums,RleViews-method} 17 | \alias{viewSums,RleViewsList-method} 18 | \alias{viewMeans} 19 | \alias{viewMeans,RleViews-method} 20 | \alias{viewMeans,RleViewsList-method} 21 | \alias{viewWhichMins} 22 | \alias{viewWhichMins,RleViews-method} 23 | \alias{viewWhichMins,RleViewsList-method} 24 | \alias{viewWhichMaxs} 25 | \alias{viewWhichMaxs,RleViews-method} 26 | \alias{viewWhichMaxs,RleViewsList-method} 27 | \alias{viewRangeMins} 28 | \alias{viewRangeMins,RleViews-method} 29 | \alias{viewRangeMins,RleViewsList-method} 30 | \alias{viewRangeMaxs} 31 | \alias{viewRangeMaxs,RleViews-method} 32 | \alias{viewRangeMaxs,RleViewsList-method} 33 | 34 | \alias{Summary,Views-method} 35 | \alias{mean,Views-method} 36 | \alias{max,Views-method} 37 | \alias{min,Views-method} 38 | \alias{sum,Views-method} 39 | \alias{which.min,Views-method} 40 | \alias{which.max,Views-method} 41 | 42 | 43 | \title{Summarize views on a vector-like object with numeric values} 44 | 45 | \description{ 46 | \code{viewApply} applies a function on each view of a \link{Views} or 47 | \link{ViewsList} object. 48 | 49 | \code{viewMins}, \code{viewMaxs}, \code{viewSums}, \code{viewMeans} 50 | calculate respectively the minima, maxima, sums, and means of the views 51 | in a \link{Views} or \link{ViewsList} object. 52 | } 53 | 54 | \usage{ 55 | viewApply(X, FUN, ..., simplify = TRUE) 56 | 57 | viewMins(x, na.rm=FALSE) 58 | \S4method{min}{Views}(x, ..., na.rm = FALSE) 59 | 60 | viewMaxs(x, na.rm=FALSE) 61 | \S4method{max}{Views}(x, ..., na.rm = FALSE) 62 | 63 | viewSums(x, na.rm=FALSE) 64 | \S4method{sum}{Views}(x, ..., na.rm = FALSE) 65 | 66 | viewMeans(x, na.rm=FALSE) 67 | \S4method{mean}{Views}(x, ...) 68 | 69 | viewWhichMins(x, na.rm=FALSE) 70 | \S4method{which.min}{Views}(x) 71 | 72 | viewWhichMaxs(x, na.rm=FALSE) 73 | \S4method{which.max}{Views}(x) 74 | 75 | viewRangeMins(x, na.rm=FALSE) 76 | 77 | viewRangeMaxs(x, na.rm=FALSE) 78 | } 79 | 80 | \arguments{ 81 | \item{X}{ 82 | A Views object. 83 | } 84 | \item{FUN}{ 85 | The function to be applied to each view in \code{X}. 86 | } 87 | \item{...}{ 88 | Additional arguments to be passed on. 89 | } 90 | \item{simplify}{ 91 | A logical value specifying whether or not the result should be simplified 92 | to a vector or matrix if possible. 93 | } 94 | \item{x}{ 95 | An \link{RleViews} or \link{RleViewsList} object. 96 | } 97 | \item{na.rm}{ 98 | Logical indicating whether or not to include missing values in the results. 99 | } 100 | } 101 | 102 | \details{ 103 | The \code{viewMins}, \code{viewMaxs}, \code{viewSums}, and \code{viewMeans} 104 | functions provide efficient methods for calculating the specified numeric 105 | summary by performing the looping in compiled code. 106 | 107 | The \code{viewWhichMins}, \code{viewWhichMaxs}, \code{viewRangeMins}, and 108 | \code{viewRangeMaxs} functions provide efficient methods for finding the 109 | locations of the minima and maxima. 110 | } 111 | 112 | \value{ 113 | For all the functions in this man page (except \code{viewRangeMins} and 114 | \code{viewRangeMaxs}): A numeric vector of the length of \code{x} 115 | if \code{x} is an \link{RleViews} object, or a \link{List} object of 116 | the length of \code{x} if it's an \link{RleViewsList} object. 117 | 118 | For \code{viewRangeMins} and \code{viewRangeMaxs}: An \link{IRanges} 119 | object if \code{x} is an \link{RleViews} object, or an \link{IRangesList} 120 | object if it's an \link{RleViewsList} object. 121 | } 122 | 123 | \note{ 124 | For convenience, methods for \code{min}, \code{max}, \code{sum}, 125 | \code{mean}, \code{which.min} and \code{which.max} are provided as 126 | wrappers around the corresponding \code{view*} functions (which might 127 | be deprecated at some point). 128 | } 129 | 130 | \author{P. Aboyoun and H. Pagès} 131 | 132 | \seealso{ 133 | \itemize{ 134 | \item The \code{\link{slice}} function for slicing an \link{Rle} or 135 | \link{RleList} object. 136 | 137 | \item \link[XVector]{view-summarization-methods} in the \pkg{XVector} 138 | package for more view summarization methods. 139 | 140 | \item The \link{RleViews} and \link{RleViewsList} classes. 141 | 142 | \item The \code{\link{which.min}} and \code{\link{colSums}} functions. 143 | } 144 | } 145 | 146 | \examples{ 147 | ## Views derived from coverage 148 | x <- IRanges(start=c(1L, 9L, 4L, 1L, 5L, 10L), 149 | width=c(5L, 6L, 3L, 4L, 3L, 3L)) 150 | cvg <- coverage(x) 151 | cvg_views <- slice(cvg, lower=2) 152 | 153 | viewApply(cvg_views, diff) 154 | 155 | viewMins(cvg_views) 156 | viewMaxs(cvg_views) 157 | 158 | viewSums(cvg_views) 159 | viewMeans(cvg_views) 160 | 161 | viewWhichMins(cvg_views) 162 | viewWhichMaxs(cvg_views) 163 | 164 | viewRangeMins(cvg_views) 165 | viewRangeMaxs(cvg_views) 166 | } 167 | 168 | \keyword{methods} 169 | \keyword{arith} 170 | -------------------------------------------------------------------------------- /src/CompressedList_class.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Low-level manipulation of CompressedList objects * 3 | ****************************************************************************/ 4 | 5 | #include "IRanges.h" 6 | 7 | 8 | /**************************************************************************** 9 | * C-level slot getters. 10 | * 11 | * Be careful that these functions do NOT duplicate the returned slot. 12 | * Thus they cannot be made .Call entry points! 13 | */ 14 | 15 | static SEXP 16 | unlistData_symbol = NULL, 17 | partitioning_symbol = NULL; 18 | 19 | SEXP _get_CompressedList_unlistData(SEXP x) 20 | { 21 | INIT_STATIC_SYMBOL(unlistData) 22 | return GET_SLOT(x, unlistData_symbol); 23 | } 24 | 25 | SEXP _get_CompressedList_partitioning(SEXP x) 26 | { 27 | INIT_STATIC_SYMBOL(partitioning) 28 | return GET_SLOT(x, partitioning_symbol); 29 | } 30 | 31 | /* Not strict "slot getters" but very much like. */ 32 | 33 | int _get_CompressedList_length(SEXP x) 34 | { 35 | return LENGTH(_get_PartitioningByEnd_end( 36 | _get_CompressedList_partitioning(x))); 37 | } 38 | 39 | SEXP _get_CompressedList_names(SEXP x) 40 | { 41 | return _get_Partitioning_names( 42 | _get_CompressedList_partitioning(x)); 43 | } 44 | 45 | 46 | /**************************************************************************** 47 | * C-level slot setters. 48 | * 49 | * Be careful that these functions do NOT duplicate the assigned value! 50 | */ 51 | 52 | static void set_CompressedList_unlistData(SEXP x, SEXP value) 53 | { 54 | INIT_STATIC_SYMBOL(unlistData) 55 | SET_SLOT(x, unlistData_symbol, value); 56 | return; 57 | } 58 | 59 | static void set_CompressedList_partitioning(SEXP x, SEXP value) 60 | { 61 | INIT_STATIC_SYMBOL(partitioning) 62 | SET_SLOT(x, partitioning_symbol, value); 63 | return; 64 | } 65 | 66 | 67 | /**************************************************************************** 68 | * C-level constructor. 69 | */ 70 | 71 | /* Be careful that this constructor does NOT duplicate its arguments before 72 | putting them in the slots of the returned object. 73 | So don't try to make it a .Call entry point! */ 74 | SEXP _new_CompressedList(const char *classname, 75 | SEXP unlistData, SEXP partitioning) 76 | { 77 | SEXP classdef, ans; 78 | 79 | PROTECT(classdef = MAKE_CLASS(classname)); 80 | PROTECT(ans = NEW_OBJECT(classdef)); 81 | set_CompressedList_unlistData(ans, unlistData); 82 | set_CompressedList_partitioning(ans, partitioning); 83 | UNPROTECT(2); 84 | return ans; 85 | } 86 | 87 | 88 | /**************************************************************************** 89 | * C-level abstract getters for CompressedIntegerList objects. 90 | */ 91 | 92 | CompressedIntsList_holder _hold_CompressedIntegerList(SEXP x) 93 | { 94 | SEXP partitioning_end; 95 | CompressedIntsList_holder x_holder; 96 | 97 | partitioning_end = _get_PartitioningByEnd_end( 98 | _get_CompressedList_partitioning(x)); 99 | x_holder.length = LENGTH(partitioning_end); 100 | x_holder.breakpoints = INTEGER(partitioning_end); 101 | x_holder.unlisted = INTEGER(_get_CompressedList_unlistData(x)); 102 | return x_holder; 103 | } 104 | 105 | int _get_length_from_CompressedIntsList_holder( 106 | const CompressedIntsList_holder *x_holder) 107 | { 108 | return x_holder->length; 109 | } 110 | 111 | Ints_holder _get_elt_from_CompressedIntsList_holder( 112 | const CompressedIntsList_holder *x_holder, 113 | int i) 114 | { 115 | Ints_holder x_elt_holder; 116 | int offset; 117 | 118 | if (i == 0) { 119 | offset = 0; 120 | } else { 121 | offset = x_holder->breakpoints[i - 1]; 122 | } 123 | x_elt_holder.ptr = x_holder->unlisted + offset; 124 | x_elt_holder.length = x_holder->breakpoints[i] - offset; 125 | return x_elt_holder; 126 | } 127 | 128 | -------------------------------------------------------------------------------- /src/Grouping_class.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Low-level manipulation of Grouping objects * 3 | * Author: H. Pag\`es * 4 | ****************************************************************************/ 5 | #include "IRanges.h" 6 | #include "S4Vectors_interface.h" 7 | 8 | 9 | /**************************************************************************** 10 | * C-level slot getters. 11 | * 12 | * Be careful that these functions do NOT duplicate the returned slot. 13 | * Thus they cannot be made .Call entry points! 14 | */ 15 | 16 | static SEXP 17 | high2low_symbol = NULL, 18 | low2high_symbol = NULL, 19 | end_symbol = NULL, 20 | NAMES_symbol = NULL; 21 | 22 | SEXP _get_H2LGrouping_high2low(SEXP x) 23 | { 24 | INIT_STATIC_SYMBOL(high2low) 25 | return GET_SLOT(x, high2low_symbol); 26 | } 27 | 28 | SEXP _get_H2LGrouping_low2high(SEXP x) 29 | { 30 | INIT_STATIC_SYMBOL(low2high) 31 | return GET_SLOT(x, low2high_symbol); 32 | } 33 | 34 | SEXP _get_Partitioning_names(SEXP x) 35 | { 36 | INIT_STATIC_SYMBOL(NAMES) 37 | return GET_SLOT(x, NAMES_symbol); 38 | } 39 | 40 | SEXP _get_PartitioningByEnd_end(SEXP x) 41 | { 42 | INIT_STATIC_SYMBOL(end) 43 | return GET_SLOT(x, end_symbol); 44 | } 45 | 46 | 47 | /**************************************************************************** 48 | * C-level slot setters. 49 | * 50 | * Be careful that these functions do NOT duplicate the assigned value! 51 | */ 52 | 53 | static void set_Partitioning_names(SEXP x, SEXP value) 54 | { 55 | INIT_STATIC_SYMBOL(NAMES) 56 | SET_SLOT(x, NAMES_symbol, value); 57 | return; 58 | } 59 | 60 | static void set_PartitioningByEnd_end(SEXP x, SEXP value) 61 | { 62 | INIT_STATIC_SYMBOL(end) 63 | SET_SLOT(x, end_symbol, value); 64 | return; 65 | } 66 | 67 | 68 | /**************************************************************************** 69 | * C-level constructor. 70 | */ 71 | 72 | /* Be careful that this constructor does NOT duplicate its arguments before 73 | putting them in the slots of the returned object. 74 | So don't try to make it a .Call entry point! */ 75 | SEXP _new_PartitioningByEnd(const char *classname, SEXP end, SEXP names) 76 | { 77 | SEXP classdef, ans; 78 | 79 | PROTECT(classdef = MAKE_CLASS(classname)); 80 | PROTECT(ans = NEW_OBJECT(classdef)); 81 | set_PartitioningByEnd_end(ans, end); 82 | if (names == NULL) 83 | names = R_NilValue; 84 | set_Partitioning_names(ans, names); 85 | UNPROTECT(2); 86 | return ans; 87 | } 88 | 89 | 90 | /**************************************************************************** 91 | * --- .Call ENTRY POINTS --- * 92 | ****************************************************************************/ 93 | 94 | SEXP C_members_H2LGrouping(SEXP x, SEXP group_ids) 95 | { 96 | SEXP ans, x_high2low, x_low2high, x_low2high_elt; 97 | int x_length, nids, ans_length, i, j, group_id, *ans_elt; 98 | 99 | if (TYPEOF(group_ids) != INTSXP) 100 | error("the group ids must be integers"); 101 | x_high2low = _get_H2LGrouping_high2low(x); 102 | x_low2high = _get_H2LGrouping_low2high(x); 103 | x_length = LENGTH(x_low2high); /* same as LENGTH(x_high2low) */ 104 | nids = LENGTH(group_ids); 105 | 106 | /* 1st pass: determine 'ans_length' */ 107 | ans_length = 0; 108 | for (j = 0; j < nids; j++) { 109 | group_id = INTEGER(group_ids)[j]; 110 | if (group_id == NA_INTEGER) 111 | error("some group ids are NAs"); 112 | i = group_id - 1; 113 | if (i < 0 || i >= x_length) 114 | error("subscript out of bounds"); 115 | if (INTEGER(x_high2low)[i] != NA_INTEGER) 116 | continue; 117 | ans_length++; 118 | x_low2high_elt = VECTOR_ELT(x_low2high, i); 119 | if (x_low2high_elt == R_NilValue) 120 | continue; 121 | ans_length += LENGTH(x_low2high_elt); 122 | } 123 | PROTECT(ans = NEW_INTEGER(ans_length)); 124 | 125 | /* 2nd pass: fill 'ans' */ 126 | ans_elt = INTEGER(ans); 127 | for (j = 0; j < nids; j++) 128 | { 129 | group_id = INTEGER(group_ids)[j]; 130 | i = group_id - 1; 131 | if (INTEGER(x_high2low)[i] != NA_INTEGER) 132 | continue; 133 | *(ans_elt++) = i + 1; 134 | x_low2high_elt = VECTOR_ELT(x_low2high, i); 135 | if (x_low2high_elt == R_NilValue) 136 | continue; 137 | memcpy(ans_elt, INTEGER(x_low2high_elt), 138 | sizeof(int) * LENGTH(x_low2high_elt)); 139 | ans_elt += LENGTH(x_low2high_elt); 140 | } 141 | 142 | sort_int_array(INTEGER(ans), ans_length, 0); 143 | UNPROTECT(1); 144 | return ans; 145 | } 146 | 147 | SEXP C_vmembers_H2LGrouping(SEXP x, SEXP group_ids_list) 148 | { 149 | SEXP ans, group_ids; 150 | int ans_length, i; 151 | 152 | ans_length = LENGTH(group_ids_list); 153 | PROTECT(ans = NEW_LIST(ans_length)); 154 | for (i = 0; i < ans_length; i++) { 155 | group_ids = VECTOR_ELT(group_ids_list, i); 156 | if (TYPEOF(group_ids) != INTSXP) 157 | error("'L' must be a list of integer vectors"); 158 | SET_VECTOR_ELT(ans, i, C_members_H2LGrouping(x, group_ids)); 159 | } 160 | UNPROTECT(1); 161 | return ans; 162 | } 163 | 164 | -------------------------------------------------------------------------------- /src/R_init_IRanges.c: -------------------------------------------------------------------------------- 1 | #include "IRanges.h" 2 | 3 | #define CALLMETHOD_DEF(fun, numArgs) {#fun, (DL_FUNC) &fun, numArgs} 4 | 5 | #define REGISTER_CCALLABLE(fun) \ 6 | R_RegisterCCallable("IRanges", #fun, (DL_FUNC) &fun) 7 | 8 | static const R_CallMethodDef callMethods[] = { 9 | 10 | /* Ranges_class.c */ 11 | CALLMETHOD_DEF(C_validate_Ranges, 3), 12 | 13 | /* IPosRanges_comparison.c */ 14 | CALLMETHOD_DEF(C_pcompare_IPosRanges, 4), 15 | 16 | /* IRanges_class.c */ 17 | CALLMETHOD_DEF(C_isNormal_IRanges, 1), 18 | CALLMETHOD_DEF(C_from_integer_to_IRanges, 1), 19 | CALLMETHOD_DEF(C_from_logical_to_NormalIRanges, 1), 20 | 21 | /* IRanges_constructor.c */ 22 | CALLMETHOD_DEF(C_solve_start_end_width, 3), 23 | CALLMETHOD_DEF(C_solve_user_SEW, 6), 24 | 25 | /* Grouping_class.c */ 26 | CALLMETHOD_DEF(C_members_H2LGrouping, 2), 27 | CALLMETHOD_DEF(C_vmembers_H2LGrouping, 2), 28 | 29 | /* RleViews_utils.c */ 30 | CALLMETHOD_DEF(C_summarize_RleViews, 4), 31 | 32 | /* SimpleIRangesList_class.c */ 33 | CALLMETHOD_DEF(C_isNormal_SimpleIRangesList, 2), 34 | CALLMETHOD_DEF(C_min_SimpleNormalIRangesList, 1), 35 | CALLMETHOD_DEF(C_max_SimpleNormalIRangesList, 1), 36 | 37 | /* CompressedIRangesList_class.c */ 38 | CALLMETHOD_DEF(C_isNormal_CompressedIRangesList, 2), 39 | CALLMETHOD_DEF(C_summary_CompressedIRangesList, 1), 40 | CALLMETHOD_DEF(C_min_CompressedNormalIRangesList, 2), 41 | CALLMETHOD_DEF(C_max_CompressedNormalIRangesList, 2), 42 | 43 | /* inter_range_methods.c */ 44 | CALLMETHOD_DEF(C_range_IRanges, 1), 45 | CALLMETHOD_DEF(C_reduce_IntegerRanges, 6), 46 | CALLMETHOD_DEF(C_reduce_CompressedIRangesList, 4), 47 | CALLMETHOD_DEF(C_gaps_IntegerRanges, 4), 48 | CALLMETHOD_DEF(C_gaps_CompressedIRangesList, 3), 49 | CALLMETHOD_DEF(C_disjointBins_IntegerRanges, 2), 50 | 51 | /* coverage_methods.c */ 52 | CALLMETHOD_DEF(C_coverage_IRanges, 6), 53 | CALLMETHOD_DEF(C_coverage_CompressedIRangesList, 6), 54 | 55 | /* NCList.c */ 56 | CALLMETHOD_DEF(C_new_NCList, 0), 57 | CALLMETHOD_DEF(C_free_NCList, 1), 58 | CALLMETHOD_DEF(C_build_NCList, 4), 59 | CALLMETHOD_DEF(C_new_NCListAsINTSXP_from_NCList, 1), 60 | CALLMETHOD_DEF(C_print_NCListAsINTSXP, 3), 61 | CALLMETHOD_DEF(C_find_overlaps_NCList, 11), 62 | CALLMETHOD_DEF(C_find_overlaps_in_groups_NCList, 15), 63 | 64 | /* CompressedAtomicList_utils.c */ 65 | CALLMETHOD_DEF(C_sum_CompressedLogicalList, 2), 66 | CALLMETHOD_DEF(C_sum_CompressedIntegerList, 2), 67 | CALLMETHOD_DEF(C_sum_CompressedNumericList, 2), 68 | CALLMETHOD_DEF(C_prod_CompressedLogicalList, 2), 69 | CALLMETHOD_DEF(C_prod_CompressedIntegerList, 2), 70 | CALLMETHOD_DEF(C_prod_CompressedNumericList, 2), 71 | CALLMETHOD_DEF(C_min_CompressedLogicalList, 2), 72 | CALLMETHOD_DEF(C_min_CompressedIntegerList, 2), 73 | CALLMETHOD_DEF(C_min_CompressedNumericList, 2), 74 | CALLMETHOD_DEF(C_max_CompressedLogicalList, 2), 75 | CALLMETHOD_DEF(C_max_CompressedIntegerList, 2), 76 | CALLMETHOD_DEF(C_max_CompressedNumericList, 2), 77 | CALLMETHOD_DEF(C_which_min_CompressedLogicalList, 1), 78 | CALLMETHOD_DEF(C_which_min_CompressedIntegerList, 1), 79 | CALLMETHOD_DEF(C_which_min_CompressedNumericList, 1), 80 | CALLMETHOD_DEF(C_which_max_CompressedLogicalList, 1), 81 | CALLMETHOD_DEF(C_which_max_CompressedIntegerList, 1), 82 | CALLMETHOD_DEF(C_which_max_CompressedNumericList, 1), 83 | CALLMETHOD_DEF(C_is_unsorted_CompressedLogicalList, 3), 84 | CALLMETHOD_DEF(C_is_unsorted_CompressedIntegerList, 3), 85 | CALLMETHOD_DEF(C_is_unsorted_CompressedNumericList, 3), 86 | 87 | /* extractListFragments.c */ 88 | CALLMETHOD_DEF(C_find_partition_overlaps, 3), 89 | 90 | {NULL, NULL, 0} 91 | }; 92 | 93 | 94 | void R_init_IRanges(DllInfo *info) 95 | { 96 | R_registerRoutines(info, NULL, callMethods, NULL, NULL); 97 | 98 | /* IPosRanges_comparison.c */ 99 | REGISTER_CCALLABLE(_overlap_code); 100 | REGISTER_CCALLABLE(_invert_overlap_code); 101 | 102 | /* IRanges_class.c */ 103 | REGISTER_CCALLABLE(_get_IRanges_start); 104 | REGISTER_CCALLABLE(_get_IRanges_width); 105 | REGISTER_CCALLABLE(_get_IRanges_names); 106 | REGISTER_CCALLABLE(_get_IRanges_length); 107 | REGISTER_CCALLABLE(_hold_IRanges); 108 | REGISTER_CCALLABLE(_get_length_from_IRanges_holder); 109 | REGISTER_CCALLABLE(_get_width_elt_from_IRanges_holder); 110 | REGISTER_CCALLABLE(_get_start_elt_from_IRanges_holder); 111 | REGISTER_CCALLABLE(_get_end_elt_from_IRanges_holder); 112 | REGISTER_CCALLABLE(_get_names_elt_from_IRanges_holder); 113 | REGISTER_CCALLABLE(_get_linear_subset_from_IRanges_holder); 114 | REGISTER_CCALLABLE(_set_IRanges_names); 115 | REGISTER_CCALLABLE(_copy_IRanges_slots); 116 | REGISTER_CCALLABLE(_new_IRanges); 117 | REGISTER_CCALLABLE(_new_IRanges_from_IntPairAE); 118 | REGISTER_CCALLABLE(_new_list_of_IRanges_from_IntPairAEAE); 119 | REGISTER_CCALLABLE(_alloc_IRanges); 120 | 121 | /* Grouping_class.c */ 122 | REGISTER_CCALLABLE(_get_H2LGrouping_high2low); 123 | REGISTER_CCALLABLE(_get_H2LGrouping_low2high); 124 | REGISTER_CCALLABLE(_get_Partitioning_names); 125 | REGISTER_CCALLABLE(_get_PartitioningByEnd_end); 126 | REGISTER_CCALLABLE(_new_PartitioningByEnd); 127 | 128 | /* CompressedList_class.c */ 129 | REGISTER_CCALLABLE(_get_CompressedList_unlistData); 130 | REGISTER_CCALLABLE(_get_CompressedList_partitioning); 131 | REGISTER_CCALLABLE(_get_CompressedList_length); 132 | REGISTER_CCALLABLE(_get_CompressedList_names); 133 | REGISTER_CCALLABLE(_new_CompressedList); 134 | REGISTER_CCALLABLE(_hold_CompressedIntegerList); 135 | REGISTER_CCALLABLE(_get_length_from_CompressedIntsList_holder); 136 | REGISTER_CCALLABLE(_get_elt_from_CompressedIntsList_holder); 137 | 138 | /* CompressedIRangesList_class.c */ 139 | REGISTER_CCALLABLE(_hold_CompressedIRangesList); 140 | REGISTER_CCALLABLE(_get_length_from_CompressedIRangesList_holder); 141 | REGISTER_CCALLABLE(_get_elt_from_CompressedIRangesList_holder); 142 | REGISTER_CCALLABLE(_get_eltNROWS_from_CompressedIRangesList_holder); 143 | 144 | return; 145 | } 146 | 147 | -------------------------------------------------------------------------------- /src/Ranges_class.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Low-level manipulation of IntegerRanges objects * 3 | * Author: H. Pag\`es * 4 | ****************************************************************************/ 5 | #include "IRanges.h" 6 | #include "S4Vectors_interface.h" 7 | 8 | 9 | /* 10 | * --- .Call ENTRY POINT --- 11 | * Doesn't raise an error but returns NULL or a single string describing the 12 | * first encountered validity failure. 13 | */ 14 | SEXP C_validate_Ranges(SEXP x_start, SEXP x_end, SEXP x_width) 15 | { 16 | static char validity_failures[200]; 17 | 18 | int x_len, i, tmp; 19 | const int *x_start_p, *x_end_p, *x_width_p; 20 | 21 | if (!IS_INTEGER(x_start) || 22 | !IS_INTEGER(x_end) || 23 | !IS_INTEGER(x_width)) 24 | { 25 | snprintf(validity_failures, sizeof(validity_failures), 26 | "'%s', '%s', and '%s' must be integer vectors", 27 | "start(x)", "end(x)", "width(x)"); 28 | goto failure; 29 | } 30 | x_len = LENGTH(x_start); 31 | if (LENGTH(x_end) != x_len || 32 | LENGTH(x_width) != x_len) 33 | { 34 | snprintf(validity_failures, sizeof(validity_failures), 35 | "'%s', '%s', and '%s' must have the same length", 36 | "start(x)", "end(x)", "width(x)"); 37 | goto failure; 38 | } 39 | for (i = 0, x_start_p = INTEGER(x_start), 40 | x_end_p = INTEGER(x_end), 41 | x_width_p = INTEGER(x_width); 42 | i < x_len; 43 | i++, x_start_p++, x_end_p++, x_width_p++) 44 | { 45 | if (*x_start_p == NA_INTEGER || 46 | *x_end_p == NA_INTEGER || 47 | *x_width_p == NA_INTEGER) 48 | { 49 | snprintf(validity_failures, sizeof(validity_failures), 50 | "'%s', '%s', and '%s' cannot contain NAs", 51 | "start(x)", "end(x)", "width(x)"); 52 | goto failure; 53 | } 54 | if (*x_width_p < 0) { 55 | snprintf(validity_failures, sizeof(validity_failures), 56 | "'%s' cannot contain negative integers", 57 | "width(x)"); 58 | goto failure; 59 | } 60 | /* Safe because NA_INTEGER == INT_MIN (see R_ext/Arith.h) */ 61 | tmp = *x_start_p - 1; 62 | /* The purpose of the 1st part of the test (the part before ||) 63 | is to avoid an integer overflow during the 2nd part of the 64 | test (the part after ||). */ 65 | if (tmp > INT_MAX - *x_width_p || 66 | tmp + *x_width_p != *x_end_p) 67 | { 68 | snprintf(validity_failures, sizeof(validity_failures), 69 | "'%s[i] - %s[i] != %s[i] + 1' for i = %d", 70 | "end(x)", "start(x)", "width(x)", i + 1); 71 | goto failure; 72 | } 73 | } 74 | return R_NilValue; 75 | failure: 76 | return mkString(validity_failures); 77 | } 78 | 79 | -------------------------------------------------------------------------------- /src/S4Vectors_stubs.c: -------------------------------------------------------------------------------- 1 | #include "_S4Vectors_stubs.c" 2 | -------------------------------------------------------------------------------- /src/SimpleIRangesList_class.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Low-level manipulation of SimpleIRangesList objects * 3 | ****************************************************************************/ 4 | #include "IRanges.h" 5 | #include 6 | 7 | #define R_INT_MIN (1+INT_MIN) 8 | 9 | /* 10 | * --- .Call ENTRY POINT --- 11 | */ 12 | SEXP C_isNormal_SimpleIRangesList(SEXP x, SEXP use_names) 13 | { 14 | SEXP list_ir, ans, ans_names; 15 | IRanges_holder ir_holder; 16 | int x_len, i; 17 | 18 | list_ir = GET_SLOT(x, install("listData")); 19 | x_len = LENGTH(list_ir); 20 | PROTECT(ans = NEW_LOGICAL(x_len)); 21 | for (i = 0; i < x_len; i++) { 22 | ir_holder = _hold_IRanges(VECTOR_ELT(list_ir, i)); 23 | LOGICAL(ans)[i] = _is_normal_IRanges_holder(&ir_holder); 24 | } 25 | if (LOGICAL(use_names)[0]) { 26 | PROTECT(ans_names = duplicate(GET_NAMES(list_ir))); 27 | SET_NAMES(ans, ans_names); 28 | UNPROTECT(1); 29 | } 30 | UNPROTECT(1); 31 | return ans; 32 | } 33 | 34 | /* 35 | * --- .Call ENTRY POINT --- 36 | */ 37 | SEXP C_min_SimpleNormalIRangesList(SEXP x) 38 | { 39 | SEXP list_ir, ans, ans_names; 40 | IRanges_holder ir_holder; 41 | int x_len, ir_len, i; 42 | int *ans_elt; 43 | 44 | list_ir = GET_SLOT(x, install("listData")); 45 | x_len = LENGTH(list_ir); 46 | PROTECT(ans = NEW_INTEGER(x_len)); 47 | for (i = 0, ans_elt = INTEGER(ans); i < x_len; i++, ans_elt++) { 48 | ir_holder = _hold_IRanges(VECTOR_ELT(list_ir, i)); 49 | ir_len = _get_length_from_IRanges_holder(&ir_holder); 50 | if (ir_len == 0) { 51 | *ans_elt = INT_MAX; 52 | } else { 53 | *ans_elt = _get_start_elt_from_IRanges_holder(&ir_holder, 0); 54 | } 55 | } 56 | PROTECT(ans_names = duplicate(GET_NAMES(list_ir))); 57 | SET_NAMES(ans, ans_names); 58 | UNPROTECT(2); 59 | return ans; 60 | } 61 | 62 | /* 63 | * --- .Call ENTRY POINT --- 64 | */ 65 | SEXP C_max_SimpleNormalIRangesList(SEXP x) 66 | { 67 | SEXP list_ir, ans, ans_names; 68 | IRanges_holder ir_holder; 69 | int x_len, ir_len, i; 70 | int *ans_elt; 71 | 72 | list_ir = GET_SLOT(x, install("listData")); 73 | x_len = LENGTH(list_ir); 74 | PROTECT(ans = NEW_INTEGER(x_len)); 75 | for (i = 0, ans_elt = INTEGER(ans); i < x_len; i++, ans_elt++) { 76 | ir_holder = _hold_IRanges(VECTOR_ELT(list_ir, i)); 77 | ir_len = _get_length_from_IRanges_holder(&ir_holder); 78 | if (ir_len == 0) { 79 | *ans_elt = R_INT_MIN; 80 | } else { 81 | *ans_elt = _get_end_elt_from_IRanges_holder(&ir_holder, ir_len - 1); 82 | } 83 | } 84 | PROTECT(ans_names = duplicate(GET_NAMES(list_ir))); 85 | SET_NAMES(ans, ans_names); 86 | UNPROTECT(2); 87 | return ans; 88 | } 89 | -------------------------------------------------------------------------------- /src/extractListFragments.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * A Nested Containment List implementation * 3 | * Author: H. Pag\`es * 4 | ****************************************************************************/ 5 | #include "IRanges.h" 6 | #include "S4Vectors_interface.h" 7 | 8 | /* 9 | * --- .Call ENTRY POINT --- 10 | * Args: 11 | * q_end, s_end: Integer vectors containing the breakpoints of 2 12 | * compatible Partitioning objects. 13 | * with_split_partitions: TRUE or FALSE. 14 | * Find the overlaps between 2 Partitioning objects in linear time. Note that, 15 | * more generally speaking, the overlaps between 2 IntegerRanges derivatives 16 | * that are both disjoint and sorted can be found in linear time. However, the 17 | * algorithm implemented below is only for Partitioning objects (which are 18 | * a particular type of such objects). Also note that, although findOverlaps() 19 | * could be used for this, it isn't as efficient as the algorithm below 20 | * because of the cost of building a Nested Containment List object and using 21 | * a binary search on it. 22 | * If 'with_split_partitions' is FALSE, return a list of 2 sorted integer 23 | * vectors of the same length, the 1st one for the query hits and the 2nd one 24 | * for the subject hits. If 'with_split_partitions' is TRUE, a 3rd list 25 | * element that is also a sorted integer vector parallel to the first 2 26 | * vectors is added. This vector contains the breakpoints of the Partitioning 27 | * object obtained by splitting the query by the subject (or vice-versa, this 28 | * split is commutative). 29 | */ 30 | SEXP C_find_partition_overlaps(SEXP q_end, SEXP s_end, 31 | SEXP with_split_partitions) 32 | { 33 | int q_len, s_len, q_prev_end, s_prev_end, i, j; 34 | IntPairAE *hits_buf; 35 | IntAE *split_partitions_buf; 36 | const int *q_end_p, *s_end_p; 37 | SEXP ans, ans_elt; 38 | 39 | q_len = LENGTH(q_end); 40 | s_len = LENGTH(s_end); 41 | hits_buf = new_IntPairAE(0, 0); 42 | if (LOGICAL(with_split_partitions)[0]) 43 | split_partitions_buf = new_IntAE(0, 0, 0); 44 | q_end_p = INTEGER(q_end); 45 | s_end_p = INTEGER(s_end); 46 | q_prev_end = s_prev_end = 0; 47 | i = j = 1; 48 | while (i <= q_len && j <= s_len) { 49 | if (q_prev_end == s_prev_end) { 50 | if (*q_end_p == q_prev_end) { 51 | i++; 52 | q_end_p++; 53 | continue; 54 | } 55 | if (*s_end_p == s_prev_end) { 56 | j++; 57 | s_end_p++; 58 | continue; 59 | } 60 | } 61 | IntPairAE_insert_at(hits_buf, 62 | IntPairAE_get_nelt(hits_buf), i, j); 63 | if (*q_end_p < *s_end_p) { 64 | q_prev_end = *q_end_p; 65 | if (LOGICAL(with_split_partitions)[0]) 66 | IntAE_insert_at(split_partitions_buf, 67 | IntAE_get_nelt(split_partitions_buf), 68 | q_prev_end); 69 | i++; 70 | q_end_p++; 71 | continue; 72 | } 73 | if (*s_end_p < *q_end_p) { 74 | s_prev_end = *s_end_p; 75 | if (LOGICAL(with_split_partitions)[0]) 76 | IntAE_insert_at(split_partitions_buf, 77 | IntAE_get_nelt(split_partitions_buf), 78 | s_prev_end); 79 | j++; 80 | s_end_p++; 81 | continue; 82 | } 83 | q_prev_end = *q_end_p; 84 | if (LOGICAL(with_split_partitions)[0]) 85 | IntAE_insert_at(split_partitions_buf, 86 | IntAE_get_nelt(split_partitions_buf), 87 | q_prev_end); 88 | i++; 89 | q_end_p++; 90 | s_prev_end = *s_end_p; 91 | j++; 92 | s_end_p++; 93 | } 94 | 95 | ans = PROTECT(NEW_LIST(LOGICAL(with_split_partitions)[0] ? 3 : 2)); 96 | 97 | ans_elt = PROTECT(new_INTEGER_from_IntAE(hits_buf->a)); 98 | SET_VECTOR_ELT(ans, 0, ans_elt); 99 | UNPROTECT(1); 100 | 101 | ans_elt = PROTECT(new_INTEGER_from_IntAE(hits_buf->b)); 102 | SET_VECTOR_ELT(ans, 1, ans_elt); 103 | UNPROTECT(1); 104 | 105 | if (LOGICAL(with_split_partitions)[0]) { 106 | ans_elt = PROTECT(new_INTEGER_from_IntAE(split_partitions_buf)); 107 | SET_VECTOR_ELT(ans, 2, ans_elt); 108 | UNPROTECT(1); 109 | } 110 | 111 | UNPROTECT(1); 112 | return ans; 113 | } 114 | 115 | -------------------------------------------------------------------------------- /tests/run_unitTests.R: -------------------------------------------------------------------------------- 1 | require("IRanges") || stop("unable to load IRanges package") 2 | IRanges:::.test() 3 | --------------------------------------------------------------------------------