How to order a specific row in a matrix? - r

tt<-c(3,2,3,5,3,5,5,4,3,1,5,2,1,5,4,1,3,5,3,3)
ff<-matrix(tt,nrow=5)
print(ff)
print(t(apply(ff,1,sort)))
I want to order the second row only by ascending order not all rows, but it always show me all rows.

ff[2, ] <- sort(ff[2, ])
ff
# [,1] [,2] [,3] [,4]
# [1,] 3 5 5 1
# [2,] 2 2 3 5
# [3,] 3 4 1 5
# [4,] 5 3 5 3
# [5,] 3 1 4 3

You can order assign the order to the second row only:
tt<-c(3,2,3,5,3,5,5,4,3,1,5,2,1,5,4,1,3,5,3,3)
ff<-matrix(tt,nrow=5)
ff[2, ] <- ff[2, ][order(ff[2, ])]
print(ff)
[,1] [,2] [,3] [,4]
[1,] 3 5 5 1
[2,] 2 2 3 5
[3,] 3 4 1 5
[4,] 5 3 5 3
[5,] 3 1 4 3

Related

How to order a matrix by the numeric or alphabetic values of the column vectors in R?

The title with the following example should be self-explanatory:
m = unique(replicate(5, sample(1:5, 5, rep=F)), MARGIN = 2)
m
[,1] [,2] [,3] [,4] [,5]
[1,] 1 5 1 4 3
[2,] 5 1 5 1 2
[3,] 4 3 3 3 1
[4,] 3 4 4 5 5
[5,] 2 2 2 2 4
But what I want is instead:
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 3 4 5
[2,] 5 5 2 1 1
[3,] 3 4 1 3 3
[4,] 4 3 5 5 4
[5,] 2 2 4 2 2
Ideally, I would like to find a method that allows the same process to be carried out when the column vectors are words (alphabetic order).
I tried things like m[ , sort(m)] but nothing did the trick...
m[, order(m[1, ]) will order the columns by the first row. m[, order(m[1, ], m[2, ])] will order by the first row, using second row as tie-breaker. Getting fancy, m[, do.call(order, split(m, row(m)))] will order the columns by the first row, using all subsequent rows for tie-breakers. This will work character data just as well as numeric.
set.seed(47)
m = replicate(5, sample(1:5, 5, rep=F))
m
# [,1] [,2] [,3] [,4] [,5]
# [1,] 5 4 1 5 1
# [2,] 2 2 3 2 3
# [3,] 3 5 5 1 2
# [4,] 4 3 2 3 5
# [5,] 1 1 4 4 4
m[, do.call(order, split(m, row(m)))]
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 1 4 5 5
# [2,] 3 3 2 2 2
# [3,] 2 5 5 1 3
# [4,] 5 2 3 3 4
# [5,] 4 4 1 4 1

replace NA of a matrix with some values

I have this matrix:
mat=matrix(c(1,1,1,2,2,2,3,4,NA,
4,4,4,4,4,3,5,6,4,
3,3,5,5,6,8,0,9,NA,
1,1,1,1,1,4,5,6,1),nrow=4,byrow=TRUE)
print(mat)
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
# [1,] 1 1 1 2 2 2 3 4 NA
# [2,] 4 4 4 4 4 3 5 6 4
# [3,] 3 3 5 5 6 8 0 9 NA
# [4,] 1 1 1 1 1 4 5 6 1
I should replace the NA values with other values, in this way:
I have another matrix:
mat2=matrix(c(24,1,3,2, 4,4,4,4, 3,2,2,5, 1,3,5,1),nrow=4,byrow=TRUE)
[,1] [,2] [,3] [,4]
[1,] 24 1 3 2
[2,] 4 4 4 4
[3,] 3 2 2 5
[4,] 1 3 5 1
and the subset with the index of the rows with NA of the first matrix "mat":
subset=c(1,3)
I want to replcace the NA of the matrix with the colnames of the value of the row with the max value.
in this case, I will have "1" for the first row and "4" for the third one, I don't care about row 2 and 4.
Use this
mat[subset,9] <- apply(mat2[subset,],1,which.max)
mat[which(is.na(mat))] <- apply(mat2,1,max)[which(is.na(mat), arr.ind = T)[1,]]
This should replace every NA value with the maximum value from the same row in mat2. I don't have an open core to debug on so I hope this works. If you have any questions or it crashes just comment.

How to convert a list of tables into one big table in R

Using R ... I have a list of tables.
# Example data
z <- list(cbind(c(1,2), c(3,4)), cbind(c(1,2), c(3,4,5,6)), cbind(c(1,2), c(1,2,3,4,5,6)), cbind(c(1,2), c(3,4)), cbind(c(1,2), c(3,4,5,6,9,4,5,6)))
z <- setNames(z, c("Ethnicity", "Country", "Age Band", "Marital Status", "Hair Color"))
z
$Ethnicity
[,1] [,2]
[1,] 1 3
[2,] 2 4
$Country
[,1] [,2]
[1,] 1 3
[2,] 2 4
[3,] 1 5
[4,] 2 6
$`Age Band`
[,1] [,2]
[1,] 1 1
[2,] 2 2
[3,] 1 3
[4,] 2 4
[5,] 1 5
[6,] 2 6
$`Marital Status`
[,1] [,2]
[1,] 1 3
[2,] 2 4
$`Hair Color`
[,1] [,2]
[1,] 1 3
[2,] 2 4
[3,] 1 5
[4,] 2 6
[5,] 1 9
[6,] 2 4
[7,] 1 5
[8,] 2 6
I would like to "collapse" (not sure if that is the right word) this list into one super table, as the column variables are the same for every table in the list. I would want the output to look something like that which I have written below... Is there any way to do this? I tried using do.call(rbind, z) but this didn't give me the proper output.
Ethnicity
[1,] 1 3
[2,] 2 4
Country
[1,] 1 3
[2,] 2 4
[3,] 1 5
[4,] 2 6
`Age Band`
[1,] 1 1
[2,] 2 2
[3,] 1 3
[4,] 2 4
[5,] 1 5
[6,] 2 6
`Marital Status`
[1,] 1 3
[2,] 2 4
`Hair Color`
[1,] 1 3
[2,] 2 4
[3,] 1 5
[4,] 2 6
[5,] 1 9
[6,] 2 4
[7,] 1 5
[8,] 2 6
This produces your desired output if I understand it correctly:
sink("output.txt")
for (i in seq_along(z)) {
cat(names(z)[i], '\n') # print out the header
write.table(z[[i]], row.names = FALSE, col.names = FALSE)
}
sink()
I open a connection to a text file with sink then loop over your list of tables and print each one out using write.table.
It produces the following output:
Ethnicity
1 3
2 4
Country
1 3
2 4
1 5
2 6
Age Band
1 1
2 2
1 3
2 4
1 5
2 6
...

ordering matrix by vector correctly

I don't understand why I cannot order a matrix based on a vector using the order function
I have the following:
m
[,1] [,2]
[1,] 1 5
[2,] 2 5
[3,] 3 5
[4,] 4 5
[5,] 5 5
[6,] 6 5
v
[[1]]
[1] 3 1 2 4 5 6
When I use:
m[order(unlist(v)),]
I get the following, incorrectly ordered matrix.
[,1] [,2]
[1,] 2 5
[2,] 3 5
[3,] 1 5
[4,] 4 5
[5,] 5 5
[6,] 6 5
when the order that I want is what's in v
[,1] [,2]
[1,] 3 5
[2,] 1 5
[3,] 2 5
[4,] 4 5
[5,] 5 5
[6,] 6 5
Why do you guys think this is happening and how can I fix it?
Instead of
m[order(unlist(v)),]
Try
temp <- unlist(v)
m[ temp , ]
Because order returns the indexes in the order that you desire. E.g.
> x = c(3,1,2)
> order(x)
[1] 2 3 1
> x[order(x)]
[1] 1 2 3

Generating all combinations of rows of matrices (brute force) in R

I have a list of matrices (with the same number of columns), say lst_Mat and I'd like to have all row-wise combinations of matrices in this list. For example, lst_Mat could be like this:
> lst_Mat
[[1]]
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 1 3 2 4
[3,] 1 3 4 2
[4,] 2 1 3 4
[5,] 2 3 1 4
[6,] 2 3 4 1
[[2]]
[,1] [,2] [,3] [,4]
[1,] 1 3 2 4
[2,] 3 1 2 4
[3,] 3 2 1 4
[4,] 3 2 4 1
[[3]]
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 1 2 4 3
[3,] 1 3 2 4
[4,] 1 3 4 2
[5,] 1 4 2 3
[6,] 1 4 3 2
[7,] 2 1 3 4
[8,] 2 1 4 3
[9,] 2 3 1 4
[10,] 3 1 2 4
[[4]]
[,1] [,2] [,3] [,4]
[1,] 2 1 4 3
[2,] 2 3 1 4
[3,] 3 1 2 4
[4,] 3 1 4 2
[5,] 3 2 1 4
As such, the total number of combinations would be 6*4*10*5=1200. This problem is analogous to the problem of generating all possible strings of English letters (i.e. a, b, c,..., x, y, z) with a specific length. For instance: aaa, aab, aac,..., aaz, aba, abb,..., abz, aca,... and so on.
I have come up with the following solution:
lst_Mat_len=list()
C=ncol(lst_Mat[[1]])
for (i in 1:length(lst_Mat))
lst_Mat_len[[length(lst_Mat_len)+1]]=(1:nrow(lst_Mat[[i]]))
combs=do.call(expand.grid, lst_Mat_len)
for (i in 1:nrow(combs)){
M=matrix(0, 0, C)
for (j in 1:ncol(combs))
M=rbind(M, lst_Mat[[j]][combs[i,j],])
# print(M)
}
Sample output of M:
> M
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 1 3 2 4
[3,] 1 2 3 4
[4,] 2 1 4 3
> M
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 1 3 2 4
[3,] 1 2 3 4
[4,] 2 3 1 4
That is, one row per matrix, each time.
I'd appreciate any other algorithms for doing so.
Here is another solution, I changed a little bit the example to make it more reproducible:
ones <- t(rep(1, 4))
lst_Mat <- list(1:6 %*% ones, 7:11 %*% ones, 12:21 %*% ones, 22:26 %*% ones)
combs <- expand.grid( sapply(lst_Mat, function(x) 1:nrow(x)) )
nbcombs <- nrow(combs)
res <- NULL
for (i in 1:nbcombs)
res[[i]] <- t(mapply(function(mat,line) mat[line,], lst_Mat, combs[i, ]))

Resources