Get matrix element through a vector of indices - r

I'm trying to parse the coordinates of a matrix from a vector to retrieve an element.
Data:
m <- matrix(1:25, ncol = 5)
v <- c(2,3)
I'm basically trying to get the elementm[2,3], in that case the value 12, by parsing the vector as coordinates:
m[v]
but all I get is NA. I have tried m[paste(v, collapse="\",\""], which also did not work.
I know I could use
m[paste(v[1]), paste(v[2])]
but I'm trying to find a more elegant solution.
Any idea how to get this to work?

you can try
> m[matrix(v, 1)]
[1] 12
or just
> m[t(v)]
[1] 12

Few more options:
m[v[1], v[2]]
[1] 12
do.call("[", c(list(m), as.list(v)))
[1] 12
m[v[1] + (v[2]-1) * nrow(m)]
[1] 12

Related

Can someone explain to me the problem with my sum in R

for a given matrix F I want to calculate the sum of the 2-norm of its rows, so I use the function sum() but it doesn't work as I expect it to do here an example
# The matrix F
> F <- matrix(c(9,1,1,1,4,1),nrow=3)
# index of the sum i
> i=1:NROW(F)
#And here is the result
> sum(norm(F[i,], type = "2")^4)
[1] 7376.60160040254
# and if i calculate each element of the sum i get
> norm(F[1,], type = "2")^4
[1] 6724
> norm(F[2,], type = "2")^4
[1] 289
> norm(F[3,], type = "2")^4
[1] 4
I think you're looking for the apply function. It applies a function along the dimensions of a matrix.
sum(apply(F,MARGIN = 1,function(x){norm(x,type = "2")^4}))
#[1] 7017
The reason yours doesn't work is because you assigned c(1,2,3) to i. Then, when you subset F, you just get the whole matrix.
i=1:NROW(F)
i
#[1] 1 2 3
norm(F,type="2")^4
#[1] 7376.602
norm(F[1:3,],type="2")^4
#[1] 7376.602
norm(F[i,],type="2")^4
#[1] 7376.602
Disclaimer: I have not assessed the mathematical validity of this approach, only programmatically recreated the OP's desired behavior.

R Matrix Multiplication Error with Proper Dimensions

I am trying to multiply matrices in R. However, I am unable to do so without error. The multiplication of the dimensions seem right, but not sure what it could be. Here is some background on my data and what my loop is. Thanks for the help.
t
# [1] 6848
dim(A)
# [1] 2 2
dim(backward)
# [1] 6848 2
dim(B)
# [1] 6848 2
is.matrix(A)
# [1] TRUE
is.matrix(backward)
# [1] TRUE
is.matrix(B)
# [1] TRUE
for (i in (t-1):1){ #FIXXXXX
backward[i,] = t(A%*%(t(backward[i+1,])))*B[i+1,]
}
Error in A %*% (t(backward[i + 1, ])) : non-conformable arguments
By default, selecting a single row or column from a matrix results in a vector. Add drop=FALSE to your subsetting expression to keep this from happening.
t(A %*% t(backward[i+1, , drop=FALSE])) * B[i+1, , drop=FALSE]
And by the way, it would probably be a good idea to rename your t variable to something else, as t is also the transpose function.

colMeans of a sparse matrix times a matrix stored as the last element of a list

I want to get the column means for the last list element, which is a sparse matrix multiplied times a regular matrix. Whenever I use colMeans, however, I get an error. For example:
# Use the igraph package to create a sparse matrix
library(igraph)
my.lattice <- get.adjacency(graph.lattice(length = 5, dim = 2))
# Create a conformable matrix of TRUE and FALSE values
start <- matrix(sample(c(TRUE, FALSE), 50, replace = T), ncol = 2)
# Multiply the matrix times the vector, and save the results to a list
out <- list()
out[[1]] <- my.lattice %*% start
out[[2]] <- my.lattice %*% out[[1]]
# Try to get column means of the last element
colMeans(tail(out, 1)[[1]]) # Selecting first element because tail creates a list
# Error in colMeans(tail(out, 1)[[1]]) :
# 'x' must be an array of at least two dimensions
# But tail(out, 1)[[1]] seems to have two dimensions
dim(tail(out, 1)[[1]])
# [1] 25 2
Any idea what's causing this error, or what I can do about it?
It looks like explicitly calling the colMeans function from the Matrix package works:
> Matrix::colMeans(tail(out, 1)[[1]])
# [1] 4.48 5.48
Thanks to user20650 for this suggestion.

r syntax: purpose of `[1]`

I found this code on :http://onertipaday.blogspot.co.il/search/label/descriptive%20statistic
The code is describing a workaround for finding the min and max in a dataset that has inf and -inf in a vector. However I don't understand the purpose of the [1] and [2] in the last two lines of code.
data <- c(-Inf, 1,2,3,4,5,6,7,8,9,10, Inf)
max(data)
# Return Inf
min(data)
# Return -Inf
# To solve the problem I went to:
range(data, finite=TRUE)
# Then you can do
myMinimum <- range(data, finite=TRUE)[1]
myMaximum <- range(data, finite=TRUE)[2]
The range function returns a vector of length 2, with the first being the minimum and the second being the maximum.
For instance:
> a <- 15:30
> range(a)
[1] 15 30
Using the [] operator you extract the desired element
> range(a)[1]
[1] 15
> range(a)[2]
[1] 30
Or you can also do:
r <- range(a)
my.min <- r[1]
my.max <- r[2]
For more information read ?range.
Also, you can directly use the min and max functions.

R - min, max and mean of off-diagonal elements in a matrix

I have like a matrix in R and I want to get:
Max off - diagonal elements
Min off – diagonal elements
Mean off –diagonal elements
With diagonal I used max(diag(A)) , min(diag(A)) , mean(diag(A)) and worked just fine
But for off-diagonal I tried
dataD <- subset(A, V1!=V2)
Error in subset.matrix(A, V1 != V2) : object 'V1' not found
to use:
colMeans(dataD) # get the mean for columns
but I cannot get dataD b/c it says object 'V1' not found
Thanks!
Here the row() and col() helper functions are useful. Using #James A, we can get the upper off-diagonal using this little trick:
> A[row(A) == (col(A) - 1)]
[1] 5 10 15
and the lower off diagonal via this:
> A[row(A) == (col(A) + 1)]
[1] 2 7 12
These can be generalised to give whatever diagonals you want:
> A[row(A) == (col(A) - 2)]
[1] 9 14
and don't require any subsetting.
Then it is a simple matter of calling whatever function you want on these values. E.g.:
> mean(A[row(A) == (col(A) - 1)])
[1] 10
If as per my comment you mean everything but the diagonal, then use
> diag(A) <- NA
> mean(A, na.rm = TRUE)
[1] 8.5
> max(A, na.rm = TRUE)
[1] 15
> # etc. using sum(A, na.rm = TRUE), min(A, na.rm = TRUE), etc..
So this doesn't get lost, Ben Bolker suggests (in the comments) that the above code block can be done more neatly using the row() and col() functions I mentioned above:
mean(A[row(A)!=col(A)])
min(A[row(A)!=col(A)])
max(A[row(A)!=col(A)])
sum(A[row(A)!=col(A)])
which is a nicer solution all round.
In one simple line of code:
For a matrix A if you wish to find the Minimum, 1st Quartile, Median, Mean, 3rd Quartile and Maximum of the upper and lower off diagonals:
summary(c(A[upper.tri(A)],A[lower.tri(A)])).
The diag of a suitably subsetted matrix will give you the off-diagonals. For example:
A <- matrix(1:16,4)
#upper off-diagonal
diag(A[-4,-1])
[1] 5 10 15
#lower off-diagonal
diag(A[-1,-4])
[1] 2 7 12
To get a vector holding the max of the off-diagonal elements of each col or row of a matrix requires a few more steps. I was directed here when searching for help on that. Perhaps others will do the same, so I offer this solution, which I found using what I learned here.
The trick is to create a matrix of only the off-diagonal elements. Consider:
> A <- matrix(c(10,2,3, 4,10,6, 7,8,10), ncol=3)
> A
[,1] [,2] [,3]
[1,] 10 4 7
[2,] 2 10 8
[3,] 3 6 10
> apply(A, 2, max)
[1] 10 10 10
Subsetting using the suggested indexing, A[row(A)!=col(A)] produces a vector of off-diagonal elements, in column-order:
> v <- A[row(A)!=col(A)]
> v
[1] 2 3 4 6 7 8
Returning this to a matrix allows the use of apply() to apply a function of choice to a margin of only off-diagonal elements. Using the max function as an example:
> A.off <- matrix(v, ncol=3)
> A.off
[,1] [,2] [,3]
[1,] 2 4 7
[2,] 3 6 8
> v <- apply(A.off, 2, max)
> v
[1] 3 6 8
The whole operation can be compactly—and rather cryptically—coded in one line:
> v <- apply(matrix(A[row(A)!=col(A)], ncol=ncol(A)), 2, max)
> v
[1] 3 6 8
Just multiply matrix A by 1-diag (nofelements)
for example if A is a 4x4 matrix, then
mean(A*(1-diag(4)) or A*(1-diag(nrow(A)))
This is faster when you need to run the same line of code multiple times
In addition to James' answer, I want to add that you can use the diag function to directly exclude all diagonal elements of a matrix by use of A[-diag(A)]. For example, consider:
summary(A[-diag(A)])

Resources