I find people use
which(matrix==max(matrix, na.rm=FALSE))
to show both row and column index.
But my question is how do I extract row index and column index individually and then return these two values into another parameters?
like matrix=
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 3 6 7 7 2 4 3 7 1 4
[2,] 1 9 8 7 2 6 10 9 5 2
[3,] 7 10 8 4 10 5 4 8 4 4
[4,] 4 3 1 1 3 3 9 7 4 2
[5,] 1 8 1 9 9 8 1 3 7 7
[6,] 2 6 7 5 6 10 4 6 15 1
the max value is matrix[6,9]=15 how could I find row =6 and column = 9 separately and return 6 to a parameter:A, 9 to parameter:B
Thank you guys very much.
For a large matrix which.max should be more efficient than which. So, for a matrix m, we can use
A = row(m)[d <- which.max(m)]
B = col(m)[d]
Maybe a roundabout way but if the matrix is called "mat":
colmax <- {which(mat == max(mat)) %/% nrow(mat)} + 1
rowmax <- which(mat == max(mat)) %% nrow(mat)
Related
This question is an extension of a question I asked earlier.
Suppose I have a vector V1 (with two or more elements):
V1 <- 1:10
I want to sample one or several vectors that:
(1). no element is in the same position as the original vector.
(2). no element is in the same position among the new vectors.
The following two are such vectors:
9 4 7 1 2 5 3 10 6 8
5 7 4 2 3 8 9 6 10 1
Here is one way to do this :
#Define the vector
V1 <- 1:10
#Number of rows
n <- 7
#Create a matrix with the vector `V1` in each row
mat <- matrix(V1, ncol = length(V1), nrow = n, byrow = TRUE)
i <- 2
while(i <= n) {
#Get randomised V1
temp <- sample(V1)
#Check if any of the previous row does not have the same combination
if (all(colSums(t(t(mat) == temp)) == 0)) {
#Add the random vector in the matrix
mat[i, ] <- temp
i <- i + 1
}
}
mat
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#[1,] 1 2 3 4 5 6 7 8 9 10
#[2,] 4 5 6 7 10 2 1 9 3 8
#[3,] 2 6 7 9 1 3 8 10 5 4
#[4,] 9 3 1 2 4 8 6 5 10 7
#[5,] 7 8 5 3 6 9 10 4 1 2
#[6,] 3 1 4 5 8 10 9 7 2 6
#[7,] 8 4 2 10 9 1 5 6 7 3
I have two vectors and I want a new vector which elements are the sum of an element of vector 1 and an element of vector 2.
v1<-c(1,2,3,4,5,6)
v2<-c(0,1,1,2,2,1)
for(i in 1:length(v1)){
for(j in 1:length(v2)){
n<-vector()
n<-v1[i]+v2[j]
}
m<-NULL
m[n]<-m
}
When I run the loop, I get m=NULL and n is numeric class with NA. Any idea?
Perhaps we need
tapply(c(v1, v2), c(v1, v2), FUN = sum)
Or just
v1 + v2
Or could be outer
outer(v1, v2, FUN = "+")
If you want to correct your code, you can try something like this:
v1<-c(1,2,3,4,5,6)
v2<-c(0,1,1,2,2,1)
m<-matrix(rep(0,length(v1)*length(v2)), nrow=length(v1))
for(i in 1:length(v1)){
for(j in 1:length(v2)){
m[i,j] <- v1[i]+v2[j]
}
}
m
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 2 2 3 3 2
[2,] 2 3 3 4 4 3
[3,] 3 4 4 5 5 4
[4,] 4 5 5 6 6 5
[5,] 5 6 6 7 7 6
[6,] 6 7 7 8 8 7
This can also be done this way
outer(v1, v2, FUN='+')
or in this way
matrix(apply(expand.grid(1:length(v1), 1:length(v2))[2:1], 1,
function(x)v1[x[1]]+v2[x[2]]), nrow=length(v1), byrow=TRUE)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 2 2 3 3 2
[2,] 2 3 3 4 4 3
[3,] 3 4 4 5 5 4
[4,] 4 5 5 6 6 5
[5,] 5 6 6 7 7 6
[6,] 6 7 7 8 8 7
I have a 6 x 10 matrix where I have to find the row index and column index of the maximum value in each row.
set.seed(75)
amat <- matrix( sample(10, size=60, replace=T), nrow=6)
which gives me the matrix:
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 3 6 7 7 2 4 3 7 1 4
[2,] 1 9 8 7 2 6 10 9 5 2
[3,] 7 10 8 4 10 5 4 8 4 4
[4,] 4 3 1 1 3 3 9 7 4 2
[5,] 1 8 1 9 9 8 1 3 7 7
[6,] 2 6 7 5 6 10 4 6 10 1
Now, I want to navigate row by row, and get the row index and column index of the maximum value in each row.
To get the maximum value in each row, I did:
apply(amat,1,max)
[1] 7 10 10 9 9 10
How do I get the row and column indices of the first occurrence of the maximum value?
Thanks
We can use max.col
cbind(1:nrow(amat), max.col(amat, 'first'))
Is it possible in R to say - I want all indices from position i to the end of vector/matrix?
Say I want a submatrix from 3rd column onwards. I currently only know this way:
A = matrix(rep(1:8, each = 5), nrow = 5) # just generate some example matrix...
A[,3:ncol(A)] # get submatrix from 3rd column onwards
But do I really need to write ncol(A)? Isn't there any elegant way how to say "from the 3rd column onwards"? Something like A[,3:]? (or A[,3:...])?
Sometimes it's easier to tell R what you don't want. In other words, exclude columns from the matrix using negative indexing:
Here are two alternative ways that both produce the same results:
A[, -(1:2)]
A[, -seq_len(2)]
Results:
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 3 4 5 6 7 8
[2,] 3 4 5 6 7 8
[3,] 3 4 5 6 7 8
[4,] 3 4 5 6 7 8
[5,] 3 4 5 6 7 8
But to answer your question as asked: Use ncol to find the number of columns. (Similarly there is nrow to find the number of rows.)
A[, 3:ncol(A)]
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 3 4 5 6 7 8
[2,] 3 4 5 6 7 8
[3,] 3 4 5 6 7 8
[4,] 3 4 5 6 7 8
[5,] 3 4 5 6 7 8
For rows (not columns as per your example) then head() and tail() could be utilised.
A <- matrix(rep(1:8, each = 5), nrow = 5)
tail(A, 3)
is almost the same as
A[3:dim(A)[1],]
(the rownames/indices printed are different is all).
Those work for vectors and data frames too:
> tail(1:10, 4)
[1] 7 8 9 10
> tail(data.frame(A = 1:5, B = 1:5), 3)
A B
3 3 3
4 4 4
5 5 5
For the column versions, you could adapt tail(), but it is a bit trickier. I wonder if NROW() and NCOL() might be useful here, rather than dim()?:
> A[, 3:NCOL(A)]
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 3 4 5 6 7 8
[2,] 3 4 5 6 7 8
[3,] 3 4 5 6 7 8
[4,] 3 4 5 6 7 8
[5,] 3 4 5 6 7 8
Or flip this on its head and instead of asking R for things, ask it to drop things instead. Here is a function that encapsulates this:
give <- function(x, i, dimen = 1L) {
ind <- seq_len(i-1)
if(isTRUE(all.equal(dimen, 1L))) { ## rows
out <- x[-ind, ]
} else if(isTRUE(all.equal(dimen, 2L))) { ## cols
out <- x[, -ind]
} else {
stop("Only for 2d objects")
}
out
}
> give(A, 3)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 1 2 3 4 5 6 7 8
[2,] 1 2 3 4 5 6 7 8
[3,] 1 2 3 4 5 6 7 8
> give(A, 3, dimen = 2)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 3 4 5 6 7 8
[2,] 3 4 5 6 7 8
[3,] 3 4 5 6 7 8
[4,] 3 4 5 6 7 8
[5,] 3 4 5 6 7 8
You can use the following instruction:
A[, 3:length(A[, 1])]
A dplyr readable renewed approach for the same thing:
A %>% as_tibble() %>%
select(-c(V1,V2))
A %>% as_tibble() %>%
select(V3:ncol(A))
Is it possible in R to say - I want all indices from position i to the end of vector/matrix?
Say I want a submatrix from 3rd column onwards. I currently only know this way:
A = matrix(rep(1:8, each = 5), nrow = 5) # just generate some example matrix...
A[,3:ncol(A)] # get submatrix from 3rd column onwards
But do I really need to write ncol(A)? Isn't there any elegant way how to say "from the 3rd column onwards"? Something like A[,3:]? (or A[,3:...])?
Sometimes it's easier to tell R what you don't want. In other words, exclude columns from the matrix using negative indexing:
Here are two alternative ways that both produce the same results:
A[, -(1:2)]
A[, -seq_len(2)]
Results:
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 3 4 5 6 7 8
[2,] 3 4 5 6 7 8
[3,] 3 4 5 6 7 8
[4,] 3 4 5 6 7 8
[5,] 3 4 5 6 7 8
But to answer your question as asked: Use ncol to find the number of columns. (Similarly there is nrow to find the number of rows.)
A[, 3:ncol(A)]
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 3 4 5 6 7 8
[2,] 3 4 5 6 7 8
[3,] 3 4 5 6 7 8
[4,] 3 4 5 6 7 8
[5,] 3 4 5 6 7 8
For rows (not columns as per your example) then head() and tail() could be utilised.
A <- matrix(rep(1:8, each = 5), nrow = 5)
tail(A, 3)
is almost the same as
A[3:dim(A)[1],]
(the rownames/indices printed are different is all).
Those work for vectors and data frames too:
> tail(1:10, 4)
[1] 7 8 9 10
> tail(data.frame(A = 1:5, B = 1:5), 3)
A B
3 3 3
4 4 4
5 5 5
For the column versions, you could adapt tail(), but it is a bit trickier. I wonder if NROW() and NCOL() might be useful here, rather than dim()?:
> A[, 3:NCOL(A)]
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 3 4 5 6 7 8
[2,] 3 4 5 6 7 8
[3,] 3 4 5 6 7 8
[4,] 3 4 5 6 7 8
[5,] 3 4 5 6 7 8
Or flip this on its head and instead of asking R for things, ask it to drop things instead. Here is a function that encapsulates this:
give <- function(x, i, dimen = 1L) {
ind <- seq_len(i-1)
if(isTRUE(all.equal(dimen, 1L))) { ## rows
out <- x[-ind, ]
} else if(isTRUE(all.equal(dimen, 2L))) { ## cols
out <- x[, -ind]
} else {
stop("Only for 2d objects")
}
out
}
> give(A, 3)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 1 2 3 4 5 6 7 8
[2,] 1 2 3 4 5 6 7 8
[3,] 1 2 3 4 5 6 7 8
> give(A, 3, dimen = 2)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 3 4 5 6 7 8
[2,] 3 4 5 6 7 8
[3,] 3 4 5 6 7 8
[4,] 3 4 5 6 7 8
[5,] 3 4 5 6 7 8
You can use the following instruction:
A[, 3:length(A[, 1])]
A dplyr readable renewed approach for the same thing:
A %>% as_tibble() %>%
select(-c(V1,V2))
A %>% as_tibble() %>%
select(V3:ncol(A))