Is there a way to access an element in amultidimensional array using a variable to store the indexes - r

Let's say I have a matrix A with n rows and m columns. If I want to acess the element on the i'th row and j'th column I can access it as A[i,j].
I would like to know how I can save this i,j in a variable x so that I can get A[x] = A[i,j]. storing them in a vector won't help since A[i,j] != A[c(i,j)].
I would like to be able to do this for a higher dimensional array where I don't know the dimensions ahead of time because they depend on the data that is suploaded by the user.
thank you very much!
Edit
what I ended up doing:
If x is the vector representing the Indices I needed, the solution is A[matrix(x,nrow=1))

You can use cbind or calculate the position.
A <- matrix(1:12, 3)
A[2,3]
#8
A[3,1]
#3
i <- c(2,3)
j <- c(3,1)
x <- cbind(i,j)
A[x]
#[1] 8 3
x <- i + (j-1)*dim(A)[1]
A[x]
#[1] 8 3

Related

How to add a constant in a for loop by keeping the original matrix in each iteration?

For example,
x<-matrix(c(1,2,3,4),2,2)
1 2
3 4
I want to add the constant "c" to each element of the matrix separately like this.
Iteration 1
1+c 2
3 4
Iteration 2
1 2+c
3 4
Iteration 3
1 2
3+c 4
Iteration 4
1 2
3 4+c
I have tried the following R code, but it retains the updated value while performing second iteration.
x= matrix of order nxm
for(i in 1:r)
{
for(j in 1:c)
{
x[i,j]=x[i,j]+c
print(x)
}
}
In this code the values getting updated and printing the updated value for each iteration.
Please help me... Thanks in Advance.
R prefers array operations.
Any matrix x is just an array of its entries, laid out column by column. You may successively add the constant c to the first, second, third, ... entry to copies of x, so that the original x remains unchanged. Do this by constructing arrays of the same length as x with all zero entries except for c in the desired location. The code shown at the end of this post does this by concatenating a bunch of zeros, c, and more zeros so that c appears in position i:
c(rep(0,i-1), cnst, rep(0,n-i)
If you loop with i=1, 2, 3, etc, the results will work down through each column of x, moving left to right. To do the operations in the order presented in the question, which works through each row, moving top to bottom, simply apply the procedure to the transpose of x and transpose the outputs.
Even for large matrices, this approach of adding an entire array is at least twice as fast on my system as adding c just to the i position of a copy of x.
Here is R code for the general procedure. It works on any non-empty matrix x. Beware: the output consists of length(x) copies of x and therefore can be quite large. In this example--which takes about a second to run on my system--x has 10,000 entries and therefore the output has 100,000,000 entries. You might want to test it on smaller matrices first!
x <- matrix(1:(100^2), 100) # Any nonempty matrix
cnst <- 1 # Value to add successively to each term in `x`
#
# The algorithm begins here.
#
n <- length(x)
lapply(1:n, function(i) matrix(as.vector(x)+c(rep(0,i-1),cnst,rep(0,n-i)), nrow(x)))
You just need to make a copy of the matrix:
x_safely_stored <- matrix of order nxm
for(i in 1:r) {
for(j in 1:c) {
x <- x_safely_stored
x[i,j]=x[i,j]+c
print(x)
}
}

find all unique combinations of n numbers between 1 and k

I want a list of all possible sets of five (or n) numbers between 1 and 63 (or more generalizably 1 and k)
If computing time wasn't an issue, I could do something like
#Get all combenations of numbers between 1 and 63
indexCombinations <- expand.grid(1:63, 1:63, 1:63, 1:63, 1:63)
#Throw out the rows that have more than one of the same number in them
allDifferent <- apply(indexCombinations, 1, function(x){
length(x) == length(unique(x))
} # function
) # apply
indexCombinationsValid <- indexCombinations[allDifferent,]
# And then just take the unique values
indexCombinationsValidUnique <- unique(indexCombinationsValid)
The finding of unique values, I am concerned, is going to be prohibitively slow. Furthermore, I end up having to make a bunch of rows in the first place I never use. I was wondering if anyone has a more elegant and efficient way of getting a data frame or matrix of unique combinations of each of five numbers (or n numbers) between one and some some range of values.
Credit to #SymbolixAU for a very elegant solution, which I re-post here as an answer:
n <- 1:63; x <- combn(n, m = 5)

Convert a one column matrix to n x c matrix

I have a (nxc+n+c) by 1 matrix. And I want to deselect the last n+c rows and convert the rest into a nxc matrix. Below is what I've tried, but it returns a matrix with every element the same in one row. I'm not sure why is this. Could someone help me out please?
tmp=x[1:n*c,]
Membership <- matrix(tmp, nrow=n, ncol=c)
You have a vector x of length n*c + n + c, when you do the extract, you put a comma in your code.
You should do tmp=x[1:(n*c)].
Notice the importance of parenthesis, since if you do tmp=x[1:n*c], it will take the range from 1 to n, multiply it by c - giving a new range and then extract based on this new range.
For example, you want to avoid:
(1:100)[1:5*5]
[1] 5 10 15 20 25
You can also do without messing up your head with indexing:
matrix(head(x, n*c), ncol=c)

R: smallest distance between an element of vector a and an element of vector b

a and b are two vectors of real numbers.
They do not necessarily have the same length.
The distance between the ith element of a and the jth element of b is defined as abs(a[i] - b[j])
How would you compute the smallest distance between any element of a and any element of b without explicit loops?
Here is what I did: min(sapply(X=1:length(b), FUN=function(x) abs(a - b[x]))).
However, I have the feeling there is something better to do...
I'd use the dist function to create a distance matrix, and then find the minimum distance in that. This is probably much faster than an explicit loop in R (including sapply).
a = runif(23)
b = runif(10)
d_matrix = as.matrix(dist(cbind(a,b)))
d_matrix[d_matrix == 0] <- NA
sqrt(min(d_matrix, na.rm = TRUE))
Note that cbind recycles the smaller vector. So this function is probably not optimal, but for vectors that do not differ that much in size still much fast than an explicit loop.
And to find which pair of elements had this distance (although the recycling introduces some challenges here):
which(d_matrix == min(d_matrix, na.rm = TRUE), arr.ind = TRUE)
Here's an attempt:
a <- c(9,5,6); b <- c(6,9)
# a
#[1] 9 5 6
# b
#[1] 6 9
combos <- sapply(b,function(x) abs(x-a))
# or an alternative
combos <- abs(outer(a,b,FUN="-"))
You could then get the minimum distance with:
min(combos)
If you wanted to get the respective indexes of the minimum values you could do:
which(combos==min(combos),arr.ind=TRUE)
# each matrix row has the 2 indexes for the minimums
# first column is 'a' index, second is 'b' index
# row col
# [1,] 3 1
# [2,] 1 2
One-liner should work here: min(abs(outer(a, b, "-")))

Select matrix column (resp. row) as Nx1 (resp. 1xD) matrix, as opposed to vector

Let X be an N by D matrix. Selecting a submatrix of size n by d returns a matrix of those dimensions unless at least one of n and d equals 1, in which case we get a vector instead. Interestingly, R still returns a matrix of the correct dimensions even if one of n and d are 0, and the other not 1.
Now, if we are certain that n!=1, then executing cbind(X[row.subset,col.subset]) will return a matrix of the correct dimensions regardless of whether d==1 or not (here n=length(row.subset) and d=length(col.subset)). If we are certain that d!=1, then we can use rbind(...). But if both n and d can be 1, neither approach will work since we could accidentally turn a row into a column or vice versa.
As far as I can tell, one way to always get a matrix of the right dimensions is to call matrix(X[row.subset,col.subset],nrow=n,ncol=d). However, it doesn't feel like that should be the right way to go about it, plus I'm not confident that there is no performance penalty. Is there a more "native" solution?
Here's a working example:
N <- 6
D <- 3
X <- matrix(rnorm(N*D),ncol=D)
dim(X[1:2,1:2]) #returns 2 2
dim(X[1:2,1]) #returns NULL, this is a vector
dim(cbind(X[1:2,1])) #returns 2 1
dim(cbind(X[1,1:2])) #returns 2 1, but we'd like it to be 1 2
dim(rbind(X[1,1:2])) #returns 1 2
dim(rbind(X[1:2,1])) #returns 1 2, but we'd like it to be 2 1
row.subset <- 1:4
col.subset <- 2
#I _think_ this is always correct, but it's verbose:
matrix(X[row.subset,col.subset],nrow=length(row.subset),ncol=length(col.subset))
Thanks in advance.
If you don't want to simplify matrix subsets to vectors just tell [ not to drop dimensions:
> dim(X[1:2,1, drop=FALSE])
[1] 2 1
> dim(X[1,1:2, drop=FALSE])
[1] 1 2
See ?"[" for details.

Resources