Generally Disable Dimension Dropping for Matrices

Generally disable dimension dropping for matrices?

You can do it by redefining the [ function:

x <- matrix(1:4,2)

`[` <- function(...) base::`[`(...,drop=FALSE)
x[,1]
[,1]
[1,] 1
[2,] 2

You cannot override the drop argument when you call it now though, so you might want to use it sparingly and delete when done.

alternative to drop=FALSE or changing default behavior

You can redefine `[` like this:

old <- `[`
`[` <- function(...) { old(..., drop=FALSE) }

This modification should be local to the interactive scope and therefore not affect routines which rely on the other behaviour. No guarantees, though. And be prepared that code of this form will be likely to confuse readers of your code, who are used to the other semantics.

Perhaps you can make this change local to a specific function, instead of all your code?

One alternative would be writing your own class for the matrix objects, for which you can provide your own subset operator implementation. This makes sense if you construct matrices in a very limited number of places, but might be a problem if there is a large number of code paths constructing these matrices.

Subsetting R array: dimension lost when its length is 1

As you've found out by default R drops unnecessary dimensions. Adding drop=FALSE while indexing can prevent this:

> dim(ay[,1:2,])
[1] 2 4
> dim(ax[,1:2,])
[1] 2 2 4
> dim(ay[,1:2,,drop = F])
[1] 1 2 4

extract column based on row values

Likely a duplicate...but to provide an answer...

You've fallen into one of the major traps of the R Inferno; 8.1.44 where "By default dimensions of arrays are dropped when subscripting makes the dimension length 1. Subscripting with drop=FALSE overrides the default."

So, this will return what you expect:

df[, sapply (df[1, ], as.character) %in% c("Y"), drop = FALSE]

Brute force for derivation of all possible matrices in R

You can use expand.grid.

K <- 2
N <- 2
lapply(asplit(do.call(expand.grid, rep(list(0:1), K*N)), 1), matrix, N, K)
#[[1]]
# [,1] [,2]
#[1,] 0 0
#[2,] 0 0
#
#[[2]]
# [,1] [,2]
#[1,] 1 0
#[2,] 0 0
#
#[[3]]
# [,1] [,2]
#[1,] 0 0
#[2,] 1 0
#
#[[4]]
# [,1] [,2]
#[1,] 1 0
#[2,] 1 0
#
#[[5]]
# [,1] [,2]
#[1,] 0 1
#[2,] 0 0
#
#[[6]]
# [,1] [,2]
#[1,] 1 1
#[2,] 0 0
#
#[[7]]
# [,1] [,2]
#[1,] 0 1
#[2,] 1 0
#
#[[8]]
# [,1] [,2]
#[1,] 1 1
#[2,] 1 0
#
#[[9]]
# [,1] [,2]
#[1,] 0 0
#[2,] 0 1
#
#[[10]]
# [,1] [,2]
#[1,] 1 0
#[2,] 0 1
#
#[[11]]
# [,1] [,2]
#[1,] 0 0
#[2,] 1 1
#
#[[12]]
# [,1] [,2]
#[1,] 1 0
#[2,] 1 1
#
#[[13]]
# [,1] [,2]
#[1,] 0 1
#[2,] 0 1
#
#[[14]]
# [,1] [,2]
#[1,] 1 1
#[2,] 0 1
#
#[[15]]
# [,1] [,2]
#[1,] 0 1
#[2,] 1 1
#
#[[16]]
# [,1] [,2]
#[1,] 1 1
#[2,] 1 1

ut aMultiplication of matrices problems

You are actually not looking for matrix multiplication but to multiply two vectors together:

> apply(abundance, 1, `*`, unlist(minsp))
# Palm Forest
#S1 151.8228 50.6076
#S2 58.7250 0.0000
#S3 0.0000 121.1760
#S4 16.2864 16.2864
#S5 0.0000 92.2080
#S6 174.4896 10.9056
#S7 0.0000 26.2710
#S8 4.2578 0.0000
#S9 12.5190 8.3460

Or even better:

t(abundance) * unlist(minsp)

R: Is there a simple way to make ave() work for matrices?

Maybe like this:

mat.list  <- Map(matrix, split(mat, groups[col(mat)]), nrow = nrow(mat))
mean.list <- Map(rowMeans, mat.list)
do.call(cbind, mean.list[groups])

Or for greater speed:

idx.list  <- split(seq_len(ncol(mat)), groups)
get.cols <- function(mat, idx) mat[, idx, drop = FALSE]
mat.list <- lapply(idx.list, get.cols, mat = mat)
mean.list <- lapply(mat.list, rowMeans)
do.call(cbind, mean.list[groups])


Related Topics



Leave a reply



Submit