avoid R to simplify array into a matrix when subsetting - r

I'm subsetting different arrays which sometimes take dimension (x,y=1,z). In these cases R automatically converts the array into a matrix and I would like to avoid it if possible keeping the structure (x, y, z').
Here's an example:
a = array(rnorm(2*1*10), c(2,1,10)) # a is an array
b = a[,,3:5] # b is a matrix

You can use drop=FALSE
a[,,3:5, drop=FALSE]

Related

R create list or matrix

If I repeat this code
x<-1:6
n<-40
M<-200
y<-replicate(M,as.numeric(table(sample(x,n,1))))
str(y)
sometimes R decide to create a matrix and sometimes it creates a list. Can you explain me the reason for that? How can I be sure that it is a matrix or a list?
If you chose M very small, for example 10, it will almost always create a matrix. If you chose M very large, for example 2000, it will create a list.
You get a list for cases when not all the numbers in x are sampled.
You can always return a list by using simplify = FALSE.
y <- replicate(M, as.numeric(table(sample(x,n,TRUE))), simplify = FALSE)
Also, you are using 1 to set replace argument. It is better to use logical argument i.e TRUE.
To return always a matrix, we can do :
sapply(y, `[`, x)
This will append NA's for values where length is unequal.
May be it will help
[https://rafalab.github.io/dsbook/r-basics.html#data-types][1]
Vectors in matrix have to be all the same type and length
Vectors in list can contain elements of different classes and length
Try this:
x<-1
y<-2:7
z<-matrix(x,y)
z<-list(x,y)
In first case you will get matrix 2 rows and 1 column because y vector is longer
In the second case you will get a list with elements of different length.
Also
str()
function is very useful. But you can find the class of object using
class()
function.

R - Converting a multidimensional array to vector and back to multidimensional array

I have an R array start_arr with dimensions i x j x k representing number of rows, number of columns and the depth respectively. Each dimension is named. I can to convert this array to a (1-dimensional) vector intermediate_vec. I then need to convert this 1D vector back into the original i x j x k array end_arr. I'm just looking for generic functions array2vec and vec2array to do the transformation in a way that preserves how elements are arranged when going from array to vector to array (i.e. that the element at 1,1,1 goes to vector element 1 and back to array element 1,1,1; element at 1,2,1 goes to vector element 2 and back to array element 1,2,1 etc). The particular way the elements are placed in intermediate_vec isn't important, as long as they end up in the exact same positions in end_arr as in start_arr.
I can do this with a C-like iterative syntax but I'm sure there's some declarative way of doing this in R that's faster.
1) Suppose we have array arr as shown in the first line. Then use c to convert to a vector vec and perform the transformation of adding 100 to each element. Then reshape it back with the same names giving arr2.
arr <- array(1:24, 2:4, dimnames = list(letters[1:2], LETTERS[1:3], month.abb[1:4]))
vec <- c(arr)
arr2 <- replace(arr, TRUE, vec + 100)
# check
all(arr2 - arr == 100)
## [1] TRUE
2) This would also work:
arr2a <- array(vec + 100, dim(arr), dimnames = dimnames(arr))
identical(arr2, arr2a)
## [1] TRUE

Extract entries > 0 and their locations from matrix A and insert into matrix B? [duplicate]

I have extracted the array indeces of some elements I want to look at as follows:
mat = matrix(0,10,10)
arrInd = which(mat ==0,arr.ind = T)
Then I do some more operations on this matrix and eventually end up with a vector or rows rowInd and a vector of columns colInd. I want us these indeces to insert values into another matrix, say mat2. But I can't seem to figure out a way to do this without looping or doing the modular arithmetic calculation myself. I realize I could take something like
mat2[rowInd*(colInd-1)+rowInd]
In order to transform back to the 1-d indexing. But since R usually has built in functions to do this sort of thing, I was wondering if there is any more concise way to do this? It would just seem natural that such a handy data-manipulation function like which(,arr.ind=T) would have a handy inverse.
I also tried using mat2[rowInd,colInd], but this did not work.
Have a read on R intro: indexing a matrix on the use of matrix indexing. which(, arr.ind = TRUE) returns a two column matrix suitable for direct use of matrix indexing. For example:
A <- matrix(c(1L,2L,2L,1L), 2)
iv <- which(A == 1L, arr.ind = TRUE)
# row col
#[1,] 1 1
#[2,] 2 2
A[iv]
# [1] 1 1
If you have another matrix B which you want to update values according to iv, just do
B[iv] <- replacement
Maybe for some reason you've separated row index and column index into rowInd and colInd. In that case, just use
cbind(rowInd, colInd)
as indexing matrix.

Best way to feed which(,arr.ind=T) back into matrix in R?

I have extracted the array indeces of some elements I want to look at as follows:
mat = matrix(0,10,10)
arrInd = which(mat ==0,arr.ind = T)
Then I do some more operations on this matrix and eventually end up with a vector or rows rowInd and a vector of columns colInd. I want us these indeces to insert values into another matrix, say mat2. But I can't seem to figure out a way to do this without looping or doing the modular arithmetic calculation myself. I realize I could take something like
mat2[rowInd*(colInd-1)+rowInd]
In order to transform back to the 1-d indexing. But since R usually has built in functions to do this sort of thing, I was wondering if there is any more concise way to do this? It would just seem natural that such a handy data-manipulation function like which(,arr.ind=T) would have a handy inverse.
I also tried using mat2[rowInd,colInd], but this did not work.
Have a read on R intro: indexing a matrix on the use of matrix indexing. which(, arr.ind = TRUE) returns a two column matrix suitable for direct use of matrix indexing. For example:
A <- matrix(c(1L,2L,2L,1L), 2)
iv <- which(A == 1L, arr.ind = TRUE)
# row col
#[1,] 1 1
#[2,] 2 2
A[iv]
# [1] 1 1
If you have another matrix B which you want to update values according to iv, just do
B[iv] <- replacement
Maybe for some reason you've separated row index and column index into rowInd and colInd. In that case, just use
cbind(rowInd, colInd)
as indexing matrix.

Using data.table's fast expand grid CJ does not work when a sublists is integer 0

I have a large list with many sublists, each of the sublists is formed by a vector of values. To this list I aim to apply a form of fast expand grid cJ, however when confronted with one of the lists yielding integer zero the function fails. My question is how could I convert Z as per all sublists which yield integer zero are transformed into class which can be submitted to the below function. I know I could use length(Z[[4]) but I aim to have a method that can be used for lists wich may include thousands of lines and a few of them may be integer 0, so I aim to convert in Z any possible integers which may be listed.
Z <- list (c(1,2,3,4,3,2,1,2),c(1,2,3,4),c(5,6,4),c(integer(0)))
do.call ( CJ , args = Z ) # get all combinations
My question is if there is any way to change the class as a whole of Z as to succeed in sumitting the data as for the function to work and not yield an error.
# Desired Output will be equal to having the last list with a numeric 0 so it will be represented in the fast expand.grid.
Z <- list (c(1,2,3,4,3,2,1,2),c(1,2,3,4),c(5,6,4),c((0)))
do.call(CJ,Z)
CJ function comes from data.table so it is worth to add that tag to question.
There is an open FR to create CJ generic method, so it could handle different types separately.
Below the function which address your question.
library(data.table)
f = function(x){
stopifnot(is.list(x))
ll = sapply(x, length)
if(any(ll == 0L)) x[ll == 0L] = 0L
do.call(CJ, args = x)
}
x = list(c(1,2,3,4,3,2,1,2),c(1,2,3,4),c(5,6,4),c(integer(0)))
f(x)

Resources