Let's say we have a matrix something like this:
> A = matrix(
+ c(2, 4, 3, 1, 5, 7), # the data elements
+ nrow=2, # number of rows
+ ncol=3, # number of columns
+ byrow = TRUE) # fill matrix by rows
> A # print the matrix
[,1] [,2] [,3]
[1,] 2 4 3
[2,] 1 5 7
Now, I just used this small example, but imagine if the matrix was much bigger, like 200 rows and 5 columns etc. What I want to do, is to get the minimum value from column 3, and extract that row. In other words, find and get the row where is the 3rd attribute the lowest in the entire column of that data frame.
dataToReturn <- which(A== min(A[, 3])
but this doesn't work.
Another way is to use which.min
A[which.min(A[, 3]), ]
##[1] 2 4 3
You can do this with a simple subsetting via [] and min:
A[A[,3] == min(A[,3]),]
[1] 2 4 3
This reads: Return those row(s) of A where the value of column 3 equals the minimum of column 3 of A.
If you have a matrix like this:
A <- matrix(c(2,4,3,1,5,7,1,3,3), nrow=3, byrow = T)
> A
[,1] [,2] [,3]
[1,] 2 4 3
[2,] 1 5 7
[3,] 1 3 3
> A[which.min(A[, 3]), ] #returns only the first row with minimum condition
[1] 2 4 3
> A[A[,3] == min(A[,3]),] #returns all rows with minimum condition
[,1] [,2] [,3]
[1,] 2 4 3
[2,] 1 3 3
Related
I am trying to map matching columns between 2 matrices. For simplicity, I have 2 simple matrices, a and b:
a <- matrix(c(1, 2), nrow = 2, ncol = 2)
b <- matrix(c(1,2,1,2,3:8), nrow = 2, ncol = 5)
> a
[,1] [,2]
[1,] 1 1
[2,] 2 2
> b
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 3 5 7
[2,] 2 2 4 6 8
I want to create a vector of length length(a[, 1]) = 2, ie
> out
[1] 1 2
Where the first element of out is the column number in b that matches the first column of a, and the second element of out is the column number in b that matches the second column in a. I have tried
> match(data.frame(a), data.frame(b))
[1] 1 1
but I need each element of the resulting vector to be unique. Probably simple solution, but I am not seeing it. Thanks!
May be you are looking for something like intersect.
a <- matrix(c(10, 20), nrow = 2, ncol = 2)
b <- matrix(c(10,20,1,2,3:6,10,20), nrow = 2, ncol = 5)
#> b
# [,1] [,2] [,3] [,4] [,5]
#[1,] 10 1 3 5 10
#[2,] 20 2 4 6 20
#Finding matching columns in b from a. Only 1st column of a is considered
matched <- b[,1:ncol(b)] == a[,1:1]
#> matched
# [,1] [,2] [,3] [,4] [,5]
#[1,] TRUE FALSE FALSE FALSE TRUE
#[2,] TRUE FALSE FALSE FALSE TRUE
desired <- which(matched[1,], arr.ind = TRUE)
#> desired
#[1] 1 5
The matched column 1 and 5 are returned.
I guess I'm not allowed to comment on here. Anyhoo...the above answer by MKR looks good, but I would add this line before creating the "desired" object. This is to ensure every column element matches (instead of testing the first row only).
matched<-sapply(1:ncol(matched),function(x) all(matched[,x]))
I have a very simple question. I have a matrix y( 1 2 3 ) and want to access elements which are greater than 1. I do not aim to count them but want to get outputs which are 2 and 3
Do you mean something like this:
A = matrix(
c(1, 2, 3), # the data elements
nrow=1, # number of rows
ncol=3, # number of columns
byrow = TRUE)
A
[,1] [,2] [,3]
[1,] 1 2 3
Greater than 1 :
which(A > 1)
which returns:
[1] 2 3
This will return values:
A[A>1]
I have this code and can't understand how rbind.fill.matrix is used.
dtmat is a matrix with the documents on rows and words on columns.
word <- do.call(rbind.fill.matrix,lapply(1:ncol(dtmat), function(i) {
t(rep(1:length(dtmat[,i]), dtmat[,i]))
}))
I read the description of the function and says that binds matrices but cannot understand which ones and fills with NA missing columns.
From what I understand, the function replaces columns that dont bind with NA.
Lets say I have 2 matrices A with two columns col1 and col2, B with three columns col1, col2 and colA. Since I want to bind all both these matrices, but rbind only binds matrices with equal number of columns and same column names, rbind.fill.matrix binds the columns but adds NA to all values that should be in both the matrices that are not. The code below will explain it more clearly.
a <- matrix(c(1,1,2,2), nrow = 2, byrow = T)
> a
[,1] [,2]
[1,] 1 1
[2,] 2 2
>
> b <- matrix(c(1,1,1,2,2,2,3,3,3), nrow = 3, byrow = T)
> b
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 2 2 2
[3,] 3 3 3
>
> library(plyr)
> r <- rbind.fill.matrix(a,b)
> r
1 2 3
[1,] 1 1 NA
[2,] 2 2 NA
[3,] 1 1 1
[4,] 2 2 2
[5,] 3 3 3
>
>
The documentation also mentions about column names, which I think you can also understand from the example.
I have a data frame like
df<-data.frame(a=c(1,2,3),b=c(4,5,6),c=c(7,8,9),d=c(10,11,12))
a b c d
1 1 4 7 10
2 2 5 8 11
3 3 6 9 12
I want to use every row to create 3 (nrow(df)) 2*2 matrixes. 1st use 1,4,7,10, 2nd use 2,5,8,11, 3rd use 3,6,9,12. So that I can get 3 matrixes. Thank you.
We can use split to split up the dataset into list and use matrix
lapply(split.default(as.matrix(df), row(df)), matrix, 2)
If we need the matrix columns to be 1, 7 followed by 4, 10, use the byrow=TRUE
lapply(split.default(as.matrix(df), row(df)), matrix, 2, byrow=TRUE)
Or use apply with MARGIN = 1 and wrap it with list to get a list output
do.call("c", apply(df, 1, function(x) list(matrix(x, ncol=2))))
If we need a for loop, preassign a as a list with length equal to the number of rows of 'df'
a <- vector("list", nrow(df))
for(i in 1:nrow(df)){ a[[i]] <- matrix(unlist(df[i,]), ncol=2)}
a
Or if it can be stored as array
array(t(df), c(2, 2, 3))
Or using map:
m <- matrix(c(t(df)), ncol = 2, byrow = T)
p <- 2 # number of rows
Map(function(i,j) m[i:j,], seq(1,nrow(m),p), seq(p,nrow(m),p))
# [[1]]
# [,1] [,2]
# [1,] 1 4
# [2,] 7 10
# [[2]]
# [,1] [,2]
# [1,] 2 5
# [2,] 8 11
# [[3]]
# [,1] [,2]
# [1,] 3 6
# [2,] 9 12
I have
mat1 = matrix(c(2, 4, 3, 6, 7, 8), nrow=2, ncol=3)
mat2 = matrix(c(5, 6, 7, 1, 2, 3), nrow=2, ncol=3)
mat3 = matrix(c(8, 5, 8, 6, 7, 9), nrow=2, ncol=3)
which gives me 3 matrices:
[,1] [,2] [,3]
[1,] 2 3 7
[2,] 4 6 8
[,1] [,2] [,3]
[1,] 5 7 2
[2,] 6 1 3
[,1] [,2] [,3]
[1,] 8 8 7
[2,] 5 6 9
What I would like to do is compare the three matrices per row per first column, and select the row of the matrix that has the highest value on the first column.
For example: in row 1 column 1, matrix3 has the highest value (8) compared to matrix1 (2) and matrix2 (5). In row 2 column 1, matrix2 has the highest value (6). I would like to create a new matrix that copies the row of the matrix that has that highest value, resulting in:
[,1] [,2] [,3]
[1,] 8 8 7 <- From mat3
[2,] 6 1 3 <- From mat2
I know how to get a vector with the highest values from column 1, but I cannot get the whole row of the matrix copied into a new matrix. I have:
mat <- (mat1[1,])
which just copies the first row of the first matrix
[1] 2 3 7
I can select which number is the maximum number:
max(mat1[,1],mat2[,1],mat3[,1])
[1] 8
But I cannot seem to combine the two to return a matrix with the whole row.
Getting the code to loop for each row will be no problem, but I cannot seem to get it to work for the first row and as such, I am missing the essential code. Any help would be greatly appreciated. Thank you.
Are you working interactively? Do you manipulate multiple matrices spread in your workspace? A straightforward answer to your problem could be:
#which matrices have the largest element of column 1 in each row?
max.col(cbind(mat1[, 1], mat2[, 1], mat3[, 1]))
#[1] 3 2
rbind(mat3[1, ], mat2[2, ]) #use the above information to get your matrix
# [,1] [,2] [,3]
#[1,] 8 8 7
#[2,] 6 1 3
On a more ganeral use-case, a way could be:
mat_ls = list(mat1, mat2, mat3) #put your matrices in a "list"
which_col = 1 #compare column 1
which_mats = max.col(do.call(cbind, lapply(mat_ls, function(x) x[, which_col])))
do.call(rbind, lapply(seq_along(which_mats),
function(i) mat_ls[[which_mats[i]]][i, ]))
# [,1] [,2] [,3]
#[1,] 8 8 7
#[2,] 6 1 3
Probably not the prettiest solution
temp <- rbind(mat1, mat2, mat3)
rbind(temp[c(T,F),][which.max(temp[c(T,F),][, 1]),],
temp[c(F,T),][which.max(temp[c(F,T),][, 1]),])
## [,1] [,2] [,3]
## [1,] 8 8 7
## [2,] 6 1 3
You may also try:
a2 <- aperm(simplify2array( mget(ls(pattern="mat"))),c(3,2,1)) #gets all matrices with name `mat`
t(sapply(1:(dim(a2)[3]), function(i) {x1 <- a2[,,i]; x1[which.max(x1[,1]),]}))
# [,1] [,2] [,3]
#[1,] 8 8 7
#[2,] 6 1 3