Using double loop to fill a matrix in R - loops

I am using double loop to fill in the matrix using following code.
mat<-matrix(NA, nrow=2, ncol=2)
for (i in 1:2){
for (j in 3:4){
mat[i,j]<-c(i,j)
}
}
mat
The error I am getting is:
Error in '[<-'('*tmp*', i, j, value = c(3L, 1L)) :
subscript out of bounds
What am I doing wrong?

So there are two problems here. First your inner for(...) loop references columns 3:4, but there are only 2 columns.
Second, you are defining the matrix to have to have single values in the elements, but then you attempt to set each element to a vector.
If you really want a matrix of vectors, you can do it this way.
mat<-matrix(list(c(NA,NA)), nrow=2, ncol=2)
for (i in 1:2){
for (j in 1:2){
mat[i,j][[1]]<-c(i,j)
}
}
mat
# [,1] [,2]
# [1,] Integer,2 Integer,2
# [2,] Integer,2 Integer,2
mat[1,1]
# [[1]]
# [1] 1 1

Related

Element-wise multiplication between array and matrix

In R, I can have piece-wise multiplication between a matrix and a (conformal) vector, for example:
X <- matrix(c(1, 2, 3, 4), nrow = 2)
a <- c(0, 1)
X * a
Each row of the matrix is then multiplied with the corresponding vector element. I can also do the same for arrays of dimension bigger than 2:
XX <- array(X, dim = c(2, 2, 2))
a <- c(0, 1)
XX * a
Again each row is multiplied with the corresponding vector element. Can I do something similar for an 3d array and a 2d matrix? I just want every submatrix of the array to be element-wise multiplied with a matrix.
you cannot multiply it with 2d matrix, but you could try this
XX*c(1,2,3,4)
It is possible to achieve 'piece'-wise multiplication (or any arithmetic operation, really) by first constructing an appropriate array from the lesser-dimensional matrix and then performing the element-wise operation. In your example:
X <- 1:8
XX <- array(X, dim = c(2, 2, 2))
a <- c(0, 1)
# construct array for point-wise operation
expandeda <- array(a, dim=dim(XX))
XX * expandeda
The result of this shows that, as you said, the individual elements of a are applied row-wise (i.e. to the first dimension of the array):
, , 1
[,1] [,2]
[1,] 0 0
[2,] 2 4
, , 2
[,1] [,2]
[1,] 0 0
[2,] 6 8
Constructing an appropriate array using array(a, dim=dim(XX)) doesn't just work for 3d and 2d matrices but for any dimensionality of arrays, as long as length(a) == dim(XX)[1].

R getting indices of closest value in z direction for all x,y points in 3dim array

I'm trying to write a function in R which is given an 3dim array and a target value and returns a matrix of the indeces with the closest value to the target in z direction for every x,y point. If there is no value within a given margin of the target the matrix should be NA at that point.
I wrote a function which works but is too slow for the hundereds of data grids with dim(x) = c(586,538,100) I want to process. I don't know how to avoid the two for loops going over the arrays x,y indices.
x <- seq(6.5,13,len=90)
dim(x) <- c(3,3,10)
get.zvals <- function(dens_grid,layer,margin=0.2){
out <- dens_grid[,,1]
out[] <- NA
for(i in 1:dim(out)[1]){
for(j in 1:dim(out)[2]){
x <- dens_grid[i,j,]
if( sum(!is.na(x)) >2
& sum(x[x<(layer+margin) & x>(layer-margin)],na.rm=TRUE) >=1 ){
out[i,j] <- which.min(abs(x-layer))
}
}
}
return(out)
}
y <- get.zvals(x,12.06)
Using apply:
get.zvals <- function(dens_grid, layer, margin=0.2) {
apply(dens_grid, c(1,2), function(x) ifelse(any(abs(x-layer) < margin),
which.min(abs(x-layer)), NA))
}
> get.zvals(x,12.06)
[,1] [,2] [,3]
[1,] NA 9 9
[2,] NA 9 NA
[3,] 9 9 NA

How can I create a static array in R

I need to create a static array for my data structure class and I chose to code in R instead of java.
How can I create a static array? I have tried
> array <- array(1:10, dim=c(1,10))
> array
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 2 3 4 5 6 7 8 9 10
but I can still add a 11th value to the array
> array[11] <- 11
> array
[1] 1 2 3 4 5 6 7 8 9 10 11
How can I prevent this from happening?
I am also not aware of a mechanism to achieve this. But the following might give you an idea how something like a static array might be achieved.
I assing a class static_vector to a vector as follows:
x <- 1:10
class(x) <- "static_vector"
Next I define a new method for the assingment operator [<- for this class:
"[<-.static_vector" <- function(x, i, value) {
if (any(i > length(x))) {
warning("Size of vector can not be changed!")
} else {
class(x) <- NULL
x[i] <- value
class(x) <- "static_vector"
}
return (x)
}
Edit: Following nicola's remark, I added any() in the first line of the function body.
Now, the following will still work and do what is expected
x[5] <- 0
but this will issue a warning and leave x unchanged:
x[11] <- 11
There are probably other methods to define before you can be sure that there is no way to change the size of x.
You can give your array a class attribute then define a [ method for it. A simple version could be something like,
`[.thing` <- function(x, i) {
if (i > length(x)) stop("index outside range")
else x[[i]]
}
arr <- array(1:10, dim=c(1,10))
class(arr) <- c("thing", class(arr))
arr[1]
# [1] 1
arr[11]
# Error in `[.thing`(arr, 11) (from ...) : index outside range

Matrix of vectors in R

Is it possible to create matrix of vectors in R? I mean the elements of this matrix must be vectors. For example mat[1,3] == c(6,8,9)
i must create 40x40 matrix and i need to fill it manually.
This is not a matrix but an array:
myarray <- array(1:24, c(2,4,3))
myarray[1,3,]
#[1] 5 13 21
Well, you can add dimensions to a list, so that it resembles a matrix where the elements can be anything you want, including vectors of different length. For example:
foo <- as.list(numeric(2^2))
dim(foo) <- c(2,2)
# Assignment per element:
foo[[1,1]] <- 1:4
foo[[1,2]] <- 1:10
foo[[2,1]] <- "foo"
foo[[2,2]] <- list(foo)
Gives you a weird looking object:
> foo
[,1] [,2]
[1,] Integer,4 Integer,10
[2,] "foo" List,1
Where each element basically is a vector. Still, this is hardly ever the best way of doing this. If the vectors are the same length an array as described by Roland is much more appropriate.

R: Fill a matrix with a covariance function

I'm experimenting with spectral simulation for generating unconditional Gaussian realizations of a spatial variable. The variable has a covariance function c(h) = exp(-h/a), where a is the range of the covariance function and h is distance. In the first step, I need to discretize the covariance function into an array/matrix. The entries in the matrix correspond to physical locations in space (i.e. the matrix indices correspond to x and y coordinates):
cov(i,j) = exp(-sqrt((i-64)^2 + (j-64)^2) / 20) for i,j = 1 to 128
I am looking to generate a matrix in R and fill it with the covariance function related to the indices of the array. As a total beginner with R, I'm a bit lost.
stuff that expression into a function:
myfun <- function(i, j) {
exp(-sqrt((i-64)^2 + (j-64)^2) / 20)
}
Then make your "matrix" of possible i, j combinations:
n <- 128
combos <- expand.grid(i=1:n, j=1:n)
Then call your function with those two vectors:
matrix(myfun(combos$i, combos$j), nrow=n)
Using a smaller number:
> n <- 5
> combos <- expand.grid(i=1:n, j=1:n)
> matrix(myfun(combos$i, combos$j), nrow=n)
[,1] [,2] [,3] [,4] [,5]
[1,] 0.01162296 0.01203954 0.01246747 0.01290681 0.01335761
[2,] 0.01203954 0.01247458 0.01292166 0.01338085 0.01385221
[3,] 0.01246747 0.01292166 0.01338860 0.01386840 0.01436113
[4,] 0.01290681 0.01338085 0.01386840 0.01436960 0.01488451
[5,] 0.01335761 0.01385221 0.01436113 0.01488451 0.01542247
>
You could also use outer:
f <- function(i, j) {
exp(-sqrt((i-64)^2 + (j-64)^2) / 20)
}
n <- 5
outer(1:n, 1:n, f)

Resources