Take a look at permatswap() in the vegan package. Here is an example that supports both summary rows and columns, but you can relax and fix only one of the sums of rows or columns.
mat <- matrix(c(1,1,0,0,0,0,0,1,1,0,0,0,1,1,1,0,1,0,1,1), ncol = 5) set.seed(4) out <- permatswap(mat, times = 99, burnin = 20000, thin = 500, mtype = "prab")
This gives:
R> out$perm[[1]] [,1] [,2] [,3] [,4] [,5] [1,] 1 0 1 1 1 [2,] 0 1 0 1 0 [3,] 0 0 0 1 1 [4,] 1 0 0 0 1 R> out$perm[[2]] [,1] [,2] [,3] [,4] [,5] [1,] 1 1 0 1 1 [2,] 0 0 0 1 1 [3,] 1 0 0 1 0 [4,] 0 0 1 0 1
To explain the call:
out <- permatswap(mat, times = 99, burnin = 20000, thin = 500, mtype = "prab")
times - the number of randomized matrices you want, here 99burnin - the number of swaps made before we start accepting random samples. This allows the matrix from which we randomly select randomness before we begin to take each of our randomized matricesthin says only take a random draw every thin swapsmtype = "prab" says that the matrix is considered as presence / absence, i.e. binary data 0/1.
A few notes, this does not guarantee that any column or row has been randomized, but if burnin is long enough, there should be a good chance that this will happen. In addition, you can draw more random matrices than you need and drop those that do not meet all your requirements.
Your requirement for a different number of changes per line is also not considered here. Again, you can select more matrices than you want, and then discard those that do not meet this requirement.