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, ]))
Related
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
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
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
...
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
I have data with dim 10,5,2 (t,x,y) and I want to convert it to dimensions 10*5,3. i.e to append every t frame to (x,y) frame with t value.
eg:
data[1,,]=
x y
1 2
1 3
data[2,,]=
x y
5 2
1 6
I would like to convert this data to flatten array like this
x y t
1 2 1
1 3 1
5 2 2
1 6 2
I was looking if there is already R function to do this or I'd do it by looping every t array and add the recreated array at bottom of main array.
a <- array(1:8, c(2,2,2))
a[1,,]
# [,1] [,2]
#[1,] 1 5
#[2,] 3 7
a[2,,]
# [,1] [,2]
#[1,] 2 6
#[2,] 4 8
m <- matrix(aperm(a, c( 2, 1, 3)), nrow=prod(dim(a)[2:3]))
cbind(m, rep(seq_len(dim(a)[2]), each=dim(a)[1]))
# [,1] [,2] [,3]
#[1,] 1 5 1
#[2,] 3 7 1
#[3,] 2 6 2
#[4,] 4 8 2
Here's a different approach:
a <- array(c(1,5,1,1,2,2,3,6), dim = c(2,2,2) )
do.call('rbind',lapply(1:dim(a)[3], function(x) cbind(a[x,,], t = x)))
t
[1,] 1 2 1
[2,] 1 3 1
[3,] 5 2 2
[4,] 1 6 2
Also:
If ais the array.
ft <- ftable(a)
cbind(ft[,1:2], as.numeric(factor(gsub("\\_.*","",row.names(as.matrix(ft))))))
[,1] [,2] [,3]
[1,] 1 2 1
[2,] 1 3 1
[3,] 5 2 2
[4,] 1 6 2