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
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].
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
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
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.
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)