Nothing
### =========================================================================
### Compact display of an array-like object
### -------------------------------------------------------------------------
###
### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### Some wrappers around extract_array_by_Nindex()
###
### All of them return a list of 2 ordinary arrays. The dimnames need to
### propagate so we use extract_array_by_Nindex() instead of extract_array().
###
.extract_two_1Darrays <- function(x, i1, i2)
{
a <- extract_array_by_Nindex(x, list(c(i1, i2)))
ii1 <- seq_along(i1)
ii2 <- seq_along(i2) + length(i1)
x1 <- a[ii1, drop=FALSE]
x2 <- a[ii2, drop=FALSE]
list(x1, x2)
}
.extract_two_matrices_by_row <- function(x, i1, i2)
{
a <- extract_array_by_Nindex(x, list(c(i1, i2), NULL))
ii1 <- seq_along(i1)
ii2 <- seq_along(i2) + length(i1)
x1 <- a[ii1, , drop=FALSE]
x2 <- a[ii2, , drop=FALSE]
list(x1, x2)
}
.extract_two_matrices_by_col <- function(x, j1, j2)
{
a <- extract_array_by_Nindex(x, list(NULL, c(j1, j2)))
jj1 <- seq_along(j1)
jj2 <- seq_along(j2) + length(j1)
x1 <- a[ , jj1, drop=FALSE]
x2 <- a[ , jj2, drop=FALSE]
list(x1, x2)
}
.extract_four_matrices <- function(x, i1, i2, j1, j2)
{
a <- extract_array_by_Nindex(x, list(c(i1, i2), c(j1, j2)))
ii1 <- seq_along(i1)
ii2 <- seq_along(i2) + length(i1)
jj1 <- seq_along(j1)
jj2 <- seq_along(j2) + length(j1)
x11 <- a[ii1, jj1, drop=FALSE]
x21 <- a[ii2, jj1, drop=FALSE]
x12 <- a[ii1, jj2, drop=FALSE]
x22 <- a[ii2, jj2, drop=FALSE]
list(x11, x21, x12, x22)
}
### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### Some wrappers around format()
###
### 'x' must be an ordinary vector or matrix of atomic or recursive type.
### 'max.width' takes effect only if 'x' is character or list (i.e. if the
### underlying type inherits from character or list when 'x' is a matrix).
.format2 <- function(x, justify, quote=TRUE, max.width=22L)
{
if (is.character(x) && length(x) != 0L && quote) {
na_idx <- which(is.na(x))
x <- paste0("\"", x, "\"")
x[na_idx] <- "NA"
}
ans <- format(x, justify=justify)
if ((is.character(x) || is.list(x)) && length(x) != 0L) {
truncate_me <- nchar(ans) > max.width
stop <- ifelse(truncate_me, max.width - 2L, nchar(ans))
ans <- substr(ans, 1L, stop)
ans <- paste0(ans, ifelse(truncate_me, "..", ""))
}
ans
}
.format_as_character_vector <- function(x, justify, quote=TRUE)
{
x_names <- names(x)
x <- as.vector(x)
ans <- .format2(x, justify, quote)
names(ans) <- x_names
ans
}
.format_as_character_matrix <- function(x, justify, quote=TRUE)
{
x_dim <- dim(x)
x_dimnames <- dimnames(x)
x <- as.matrix(x)
ans <- .format2(x, justify, quote)
ans <- set_dim(ans, x_dim)
set_dimnames(ans, x_dimnames)
}
### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### Some low-level utilities to handle array names/dimnames
###
.wrap_subscripts <- function(i, x_names=NULL, left="[", right="]")
{
if (length(i) == 0L)
return(character(0))
if (is.null(x_names))
return(paste0(left, i, right, sep=""))
x_names[i]
}
.make_1Darray_names <- function(i1, i2, x_names, justify)
{
s1 <- .wrap_subscripts(i1, x_names)
s2 <- .wrap_subscripts(i2, x_names)
format(c(s1, ".", s2), justify=justify)
}
.make_rownames <- function(i1, i2, x_rownames, justify)
{
s1 <- .wrap_subscripts(i1, x_rownames, right=",]")
s2 <- .wrap_subscripts(i2, x_rownames, right=",]")
max_width <- max(nchar(s1, type="width"), nchar(s2, type="width"))
if (max_width <= 1L) {
ellipsis <- "."
} else if (max_width == 2L) {
ellipsis <- ".."
} else {
ellipsis <- "..."
}
format(c(s1, ellipsis, s2), justify=justify)
}
.make_colnames <- function(j1, j2, x_colnames, justify)
{
s1 <- .wrap_subscripts(j1, x_colnames, left="[,")
s2 <- .wrap_subscripts(j2, x_colnames, left="[,")
ans <- format(c(s1, s2), justify=justify)
c(head(ans, n=length(s1)), "...", tail(ans, n=length(s2)))
}
### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### The extract_and_stitch_* family of helpers
###
.extract_and_stitch_two_1Darrays <- function(x, i1, i2,
justify, quote=TRUE)
{
x12 <- .extract_two_1Darrays(x, i1, i2)
ans1 <- .format_as_character_vector(x12[[1L]], justify, quote=quote)
ans2 <- .format_as_character_vector(x12[[2L]], justify, quote=quote)
ans <- c(ans1, ".", ans2)
names(ans) <- .make_1Darray_names(i1, i2, names(x), justify)
ans
}
.extract_and_stitch_two_matrices_by_row <- function(x, i1, i2,
justify, quote=TRUE)
{
x12 <- .extract_two_matrices_by_row(x, i1, i2)
ans1 <- .format_as_character_matrix(x12[[1L]], justify, quote=quote)
ans2 <- .format_as_character_matrix(x12[[2L]], justify, quote=quote)
hdots <- rep.int(".", ncol(ans1))
ans <- rbind(ans1, matrix(hdots, nrow=1L), ans2)
rownames(ans) <- .make_rownames(i1, i2, rownames(x), justify)
ans
}
.extract_and_stitch_two_matrices_by_col <- function(x, j1, j2,
justify, quote=TRUE)
{
x12 <- .extract_two_matrices_by_col(x, j1, j2)
ans1 <- .format_as_character_matrix(x12[[1L]], justify, quote=quote)
ans2 <- .format_as_character_matrix(x12[[2L]], justify, quote=quote)
vdots <- rep.int(".", nrow(ans1))
ans <- cbind(ans1, matrix(vdots, ncol=1L), ans2)
colnames(ans) <- .make_colnames(j1, j2, colnames(x), justify)
ans
}
.extract_and_stitch_four_matrices <- function(x, i1, i2, j1, j2,
justify, quote=TRUE)
{
x1234 <- .extract_four_matrices(x, i1, i2, j1, j2)
ans11 <- .format_as_character_matrix(x1234[[1L]], justify, quote=quote)
ans21 <- .format_as_character_matrix(x1234[[2L]], justify, quote=quote)
ans12 <- .format_as_character_matrix(x1234[[3L]], justify, quote=quote)
ans22 <- .format_as_character_matrix(x1234[[4L]], justify, quote=quote)
hdots <- rep.int(".", ncol(ans11))
ans1 <- rbind(ans11, matrix(hdots, nrow=1L), ans21)
hdots <- rep.int(".", ncol(ans12))
ans2 <- rbind(ans12, matrix(hdots, nrow=1L), ans22)
vdots <- rep.int(".", nrow(ans1))
ans <- cbind(ans1, matrix(vdots, ncol=1L), ans2)
rownames(ans) <- .make_rownames(i1, i2, rownames(x), justify)
colnames(ans) <- .make_colnames(j1, j2, colnames(x), justify)
ans
}
### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### 1D array
###
.prepare_1Darray_sample <- function(x, n1, n2, justify, quote=TRUE)
{
x_len <- length(x)
x_names <- names(x)
if (x_len <= n1 + n2 + 1L) {
ans <- .format_as_character_vector(x, justify, quote=quote)
i1 <- seq_len(x_len)
i2 <- integer(0)
names(ans) <- .make_1Darray_names(i1, i2, x_names, justify)[i1]
} else {
i1 <- seq_len(n1)
i2 <- seq(to=x_len, by=1L, length.out=n2)
ans <- .extract_and_stitch_two_1Darrays(x, i1, i2, justify, quote=quote)
}
ans
}
.print_1Darray_data <- function(x, n1, n2, quote=TRUE)
{
stopifnot(length(dim(x)) == 1L)
right <- type(x) != "character"
justify <- if (right) "right" else "left"
out <- .prepare_1Darray_sample(x, n1, n2, justify, quote=quote)
print(out, quote=FALSE, right=right, max=length(out))
}
### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### 2D array
###
.rsplit_2Darray_data <- function(x, m1, m2, justify, quote=TRUE)
{
x_nrow <- nrow(x)
i1 <- seq_len(m1)
i2 <- seq(to=x_nrow, by=1L, length.out=m2)
.extract_and_stitch_two_matrices_by_row(x, i1, i2, justify, quote=quote)
}
.csplit_2Darray_data <- function(x, n1, n2, justify, quote=TRUE)
{
x_ncol <- ncol(x)
j1 <- seq_len(n1)
j2 <- seq(to=x_ncol, by=1L, length.out=n2)
.extract_and_stitch_two_matrices_by_col(x, j1, j2, justify, quote=quote)
}
.split_2Darray_data <- function(x, m1, m2, n1, n2, justify, quote=TRUE)
{
x_nrow <- nrow(x)
i1 <- seq_len(m1)
i2 <- seq(to=x_nrow, by=1L, length.out=m2)
x_ncol <- ncol(x)
j1 <- seq_len(n1)
j2 <- seq(to=x_ncol, by=1L, length.out=n2)
.extract_and_stitch_four_matrices(x, i1, i2, j1, j2, justify, quote=quote)
}
.prepare_2Darray_sample <- function(x, m1, m2, n1, n2, justify, quote=TRUE)
{
## An attempt at reducing the nb of columns to display when 'x' has
## dimnames so the object fits in getOption("width"). Won't necessarily
## pick up the optimal nb of columns so should be revisited at some point.
x_rownames <- rownames(x)
if (is.null(x_rownames)) {
rownames_width <- 6L
} else {
rownames_width <- nchar(x_rownames[[1L]])
}
half_width <- (getOption("width") - rownames_width) / 2
x_colnames <- colnames(x)
if (!is.null(x_colnames)) {
colnames1 <- head(x_colnames, n=n1)
colnames2 <- tail(x_colnames, n=n2)
n1 <- pmax(sum(cumsum(nchar(colnames1) + 1L) < half_width), 1L)
n2 <- pmax(sum(cumsum(nchar(colnames2) + 1L) < half_width), 1L)
}
x_nrow <- nrow(x)
x_ncol <- ncol(x)
if (x_nrow <= m1 + m2 + 1L) {
if (x_ncol <= n1 + n2 + 1L) {
ans <- .format_as_character_matrix(x, justify, quote=quote)
## Only needed because of this bug in base::print.default:
## https://stat.ethz.ch/pipermail/r-devel/2016-March/072479.html
## TODO: Remove when the bug is fixed.
if (is.null(colnames(ans))) {
j1 <- seq_len(ncol(ans))
j2 <- integer(0)
colnames(ans) <- .make_colnames(j1, j2, NULL, justify)[j1]
}
} else {
ans <- .csplit_2Darray_data(x, n1, n2, justify, quote=quote)
}
} else {
if (x_ncol <= n1 + n2 + 1L) {
ans <- .rsplit_2Darray_data(x, m1, m2, justify, quote=quote)
## Only needed because of this bug in base::print.default:
## https://stat.ethz.ch/pipermail/r-devel/2016-March/072479.html
## TODO: Remove when the bug is fixed.
if (is.null(colnames(ans))) {
j1 <- seq_len(ncol(ans))
j2 <- integer(0)
colnames(ans) <- .make_colnames(j1, j2, NULL, justify)[j1]
}
} else {
ans <- .split_2Darray_data(x, m1, m2, n1, n2, justify, quote=quote)
}
}
ans
}
.print_2Darray_data <- function(x, m1, m2, n1, n2, quote=TRUE)
{
stopifnot(length(dim(x)) == 2L)
right <- type(x) != "character"
justify <- if (right) "right" else "left"
out <- .prepare_2Darray_sample(x, m1, m2, n1, n2, justify, quote=quote)
print(out, quote=FALSE, right=right, max=length(out))
}
### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### Array of arbitrary dimensions
###
.print_2D_slices <- function(x, m1, m2, n1, n2, grid, idx, quote=TRUE)
{
x_dimnames <- dimnames(x)
for (i in idx) {
viewport <- grid[[i]]
s <- make_string_from_ArrayViewport(viewport, dimnames=x_dimnames,
as.2Dslice=TRUE)
cat(s, "\n", sep="")
Nindex <- makeNindexFromArrayViewport(viewport, expand.RangeNSBS=TRUE)
slice <- subset_by_Nindex(x, Nindex)
slice <- set_dim(slice, dim(slice)[1:2])
.print_2Darray_data(slice, m1, m2, n1, n2, quote=quote)
cat("\n")
}
}
.print_nDarray_data <- function(x, n1, n2, quote=TRUE)
{
x_dim <- dim(x)
x_nrow <- x_dim[[1L]]
x_ncol <- x_dim[[2L]]
if (x_ncol <= 5L) {
if (x_nrow <= 3L) {
m1 <- m2 <- 3L # print all rows of each slice
z1 <- z2 <- 3L # print first 3 and last 3 slices
} else {
m1 <- m2 <- 2L # print first 2 and last 2 rows of each slice
z1 <- z2 <- 1L # print only first and last slices
}
} else {
if (x_nrow <= 3L) {
m1 <- m2 <- 2L # print first 2 and last 2 rows of each slice
z1 <- z2 <- 2L # print first 2 and last 2 slices
} else {
m1 <- m2 <- 2L # print first 2 and last 2 rows of each slice
z1 <- z2 <- 1L # print only first and last slices
}
}
spacings <- x_dim
spacings[-(1:2)] <- 1L
grid <- RegularArrayGrid(x_dim, spacings)
nblock <- length(grid) # should be equal to prod(x_dim[-(1:2)])
if (nblock <= z1 + z2 + 1L) {
idx <- seq_len(nblock)
.print_2D_slices(x, m1, m2, n1, n2, grid, idx, quote=quote)
} else {
idx1 <- seq_len(z1)
idx2 <- seq(to=nblock, by=1L, length.out=z2)
.print_2D_slices(x, m1, m2, n1, n2, grid, idx1, quote=quote)
cat("...\n\n")
.print_2D_slices(x, m1, m2, n1, n2, grid, idx2, quote=quote)
}
}
### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### show_compact_array()
###
.print_array_data <- function(x, n1, n2, quote=TRUE)
{
x_dim <- dim(x)
if (length(x_dim) == 1L)
return(.print_1Darray_data(x, n1, n2, quote=quote))
if (length(x_dim) == 2L) {
nhead <- get_showHeadLines()
ntail <- get_showTailLines()
return(.print_2Darray_data(x, nhead, ntail, n1, n2, quote=quote))
}
.print_nDarray_data(x, n1, n2, quote=quote)
}
### NOT exported but used in the HDF5Array package!
array_as_one_line_summary <- function(x)
{
x_dim <- dim(x)
sprintf("<%s>%s %s of class %s and type \"%s\"",
paste0(x_dim, collapse=" x "),
if (is_sparse(x)) " sparse" else "",
if (length(x_dim) == 2L) "matrix" else "array",
class(x),
type(x))
}
### Work on any array-like object that complies with the "seed contract" i.e.
### that supports dim(), dimnames(), and extract_array().
### NOT exported.
show_compact_array <- function(object)
{
cat(array_as_one_line_summary(object))
if (any(dim(object) == 0L)) {
cat("\n")
return()
}
cat(":\n")
if (type(object) == "integer") {
n1 <- n2 <- 4L
} else {
n1 <- 3L
n2 <- 2L
}
.print_array_data(object, n1, n2)
}
### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### showAsCell()
###
### A re-implementation of S4Vectors:::.showAsCell_array() that avoids doing
### the "reshaping" of the object. Should work on any array-like object that
### supports extract_array().
.showAsCell_array_like <- function(object)
{
dim1 <- dim(object)[-1L]
p1 <- prod(dim1)
if (p1 == 0L)
return(rep.int("", nrow(object)))
first_cols <- lapply(seq_len(min(p1, 3L)),
function(i1) {
subscripts <- arrayInd(i1, dim1)
index <- c(list(NULL), as.list(subscripts))
as.character(extract_array(object, index))
}
)
ans <- do.call(paste, c(first_cols, list(sep=":")))
if (p1 > 3L)
ans <- paste0(ans, ":...")
ans
}
setMethod("showAsCell", "Array", .showAsCell_array_like)
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.