I have a Matrix A which looks like
A = matrix(1:9,3,3)
A
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
and a matrix of indices of elements I am interested in. Column 1 contains row indices, and column 2 contains column indices:
v = matrix(c(1, 3, 2, 2, 2, 3), nrow = 3, ncol = 2)
v
[,1] [,2]
[1,] 1 2
[2,] 3 2
[3,] 2 3
I want to use the rows and column indices in 'v' to extract numbers from 'A'; the indices correspond to the numbers 4 (A[1, 2]), 6 (A[3, 2]) and 8.
How can I extract those numbers directly from 'A' without using a loop?
When I use
A[v[ , 1], v[ , 2]]
I get
[,1] [,2] [,3]
[1,] 4 4 7
[2,] 6 6 9
[3,] 5 5 8
because R takes all combinations of the first and second column of 'v'.
What I want is an expression which gives me directly 4, 6, 8.
I could just take the diagonal elements but there must be an easier way.
From ?"[", you will find the following:
When indexing arrays by [ a single argument i can be a matrix with as many columns as there are dimensions of x; the result is then a vector with elements corresponding to the sets of indices in each row of i.
and later on...
A third form of indexing is via a numeric matrix with the one column for each dimension: each row of the index matrix then selects a single element of the array, and the result is a vector. Negative indices are not allowed in the index matrix. NA and zero values are allowed: rows of an index matrix containing a zero are ignored, whereas rows containing an NA produce an NA in the result.
Thus, what you are looking for is simply:
A[v]
Related
How to generate a matrix based on a comparison of two matrices. I have (column,row) matrix A (10,1) and B (10, 100). Matrix A is compared to each row of matrix B if the value of B is smaller than A then value B is updated to a value of A.
n.units<-100
n.option<-10
A<-rnorm(n.option,1,0.2)
B<-matrix(rnorm(n.option*n.units,1,0.2)n.col=n.units)
renew <-function(){Thresholds=obj.value }
update1 <- apply((Thresholds < obj.value),1,renew)
I am new to R programming, please give some advice to solve it.
I guess what you are trying can be achieved with pmax. Try
pmax(B, A)
You have a numeric vector A which is compared with matrix B. 1st element of A is compared with first row of B and the maximum value is selected. Same goes for all other rows since pmax recycles the shorter vector to the longer vector length. Also note that pmax(B, A) gives different structure than pmax(A, B) although the value is the same.
Just to make it easier to understand, consider this example
mat <- matrix(1:10, ncol = 5)
mat
# [,1] [,2] [,3] [,4] [,5]
#[1,] 1 3 5 7 9
#[2,] 2 4 6 8 10
pmax(mat, c(3, 7))
# [,1] [,2] [,3] [,4] [,5]
#[1,] 3 3 5 7 9
#[2,] 7 7 7 8 10
Here 1st row is compared with 3 and second row is compared with 7 and maximum value is selected.
Suppose you have a matrix a
a <- matrix(1:9, 3, 3)
a
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
and a vector b indicating which element of each row you want to extract. That is, the vector b indicates the column of the element, for instance:
b <- c(1, 3, 1)
If we want to extract the indicated data points, we can simply index each desired element like this:
a[cbind(1:nrow(a),b)]
[1] 1 8 3
I would like to do it with a negative index vector. That is, R should return a matrix where exactly one element per row is omitted (in this case, a 3x2 matrix). If I try it in a naive approach, R throws an error:
c = -b
a[cbind(1:nrow(a),c)]
Error in a[cbind(1:nrow(a), c)] :
negative values are not allowed in a matrix subscript
Thank you!
Not pretty, but you could do
b <- c(1, 3, 1) + 3 * 0:2
matrix(c(t(a))[-b], 3, 2, byrow = TRUE)
Maybe this is another naive approach. We loop over every row in the matrix and remove index specified in b.
t(sapply(seq_len(nrow(a)), function(x) a[x, -b[x]]))
# [,1] [,2]
#[1,] 4 7
#[2,] 2 5
#[3,] 6 9
Or using mapply with split
t(mapply(`[`, split(a, seq_len(nrow(a))), -b))
This question already has answers here:
Index values from a matrix using row, col indices
(4 answers)
Closed 4 years ago.
Say you have the following matrix:
mat <- matrix(1:12, nrow = 3, ncol = 4)
print(mat)
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
And you wish to extract values from the matrix with the following row and column indices:
rowind <- c(2,3,1)
colind <- c(4,4,1)
So I'm looking for the values 11 (row 2, col 4), 12 (row 3, col 4) and 1 (row 1, col 1).
If I try passing the column and row vectors into the matrix with:
mat[rowind, colind]
I get a new matrix where all permutations of rowind and colind are included:
[,1] [,2] [,3]
[1,] 11 11 2
[2,] 12 12 3
[3,] 10 10 1
How I can instead get the values relating only to the specific row and column combinations? I considered using a for loop but given my matrix and index vectors are large I feel this would be unnecessarily slow and that there is very likely a better way.
We can cbind the indices to extract the values
mat[cbind(rowind, colind)]
#[1] 11 12 1
I am looking for a clever way to force the dimensions (both nrow and ncol) of a matrix to be even without using an if statement. By force I mean subtract the first appropriate column and/or row so that both dimensions are even.
I was hoping something like this would work:
## build a matrix with odd number of columns and even number of rows
x=matrix(1:12,nrow=4,ncol=3)
## we can check which (if any) dimensions are odd with
dim(x) %% 2 ## 0,1
## I would like get a matrix that looks like
[,1] [,2]
[1,] 5 9
[2,] 6 10
[3,] 7 11
[4,] 8 12
## By using something similar to
x.even = x[-nrow(x)%%2,-ncol(x)%%2]
Obviously the last line does not give the desired result. Is there a clever way to do this without using a conditional?
Just divide nrow and ncol by 2, take floor, and multiply by 2 again
x.even = x[1:(2*floor(nrow(x)/2)),1:(2*floor(ncol(x)/2))]
One way that builds on your solution:
#start rows and columns from 1
#also subtract remainder from total rows and columns
x[1:(nrow(x) - nrow(x) %% 2), 1:(ncol(x) - ncol(x) %% 2)]
output:
[,1] [,2]
[1,] 1 5
[2,] 2 6
[3,] 3 7
[4,] 4 8
My aim is to delete specific positions in a matrix according to a vector. Just giving you a small example.
Users_pos <- c(1,2)
Items_pos <- c(3,2)
Given a Matrix A:
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
My aim according to the two Vectors User_pos and Item_pos is to delete the following values
A[1,3] and A[3,2]
I'm wondering if there's a possibility to do so without typing in the values for rows and columns by hand.
You can index k elements in a matrix A using A[X], where X is a k-row, 2-column matrix where each row is the (row, col) value of the indicated element. Therefore, you can index your two elements in A with the following indexing matrix:
rbind(Users_pos, Items_pos)
# [,1] [,2]
# Users_pos 1 2
# Items_pos 3 2
Using this indexing, you could choose to extract the information current stored with A[X] or replace those elements with A[X] <- new.values. If you, for instance, wanted to replace these elements with NA, you could do:
A[rbind(Users_pos, Items_pos)] <- NA
A
# [,1] [,2] [,3]
# [1,] 1 NA 3
# [2,] 4 5 6
# [3,] 7 NA 9