# [R] Randomising matrices

Finny Kuruvilla kuruvill at fas.harvard.edu
Fri Apr 27 14:42:39 CEST 2007

```Stephanie Dray's comments are absolutely correct.  This method will
only work with small matrics.  The below modification is much faster
than the first version that I wrote, but still slow on large
matrices.

shuffle_matrix <- function(x) {
nrow = dim(x)[1]
ncol = dim(x)[2]
cmargins <- apply(x,2,sum)
shuffled = array(length(x),dim=c(nrow,ncol))

while(1) {
for(k in 1:nrow) {
shuffled[k,] = sample(x[k,],ncol)
}
if(all(apply(shuffled,2,sum) == cmargins)) {
break
}
}
shuffled
}

On Fri, 27 Apr 2007, Stéphane Dray wrote:

> Your solution is not suitable for quite large matrices.
>
> There are several papers on the subject :
>
> e.g. :
> @ARTICLE{SD751,
> author = {Gotelli, N.J. and Entsminger, G.L.},
> title = {Swap and fill algorithms in null model analysis:rethinking the
> knight's
>   tour},
> journal = {Oecologia},
> year = {2001},
> volume = {129},
> pages = {281-291},
> endnotereftype = {Journal Article},
> keywords = {null model},
> pdf = {/home/stephane/Biblio/Articles/SD751.pdf},
> shorttitle = {Swap and fill algorithms in null model analysis:rethinking the
> knight's
>   tour}
> }
>
> There are different algorithms to solve the question but I am really not sure
> that they are implemented in R.
>
> Sincerely,
>
>
> Finny Kuruvilla wrote:
>> Hi Nick,
>>
>> This way isn't the most elegant but works well, especially if the
>> matrices aren't too large:
>>
>> # This function works on 2x2 arrays, randomizing them, but
>> # preserving row and column totals
>> shuffle_matrix <- function(x) {
>>    nrow = dim(x)[1]
>>    ncol = dim(x)[2]
>>    rmargins <- apply(x,1,sum)
>>    cmargins <- apply(x,2,sum)
>>
>>    while(1) {
>>      shuffled <- array(sample(x,length(x),replace=TRUE),dim=c(nrow,ncol))
>>      if(all(apply(shuffled,1,sum) == rmargins)) {
>>        if(all(apply(shuffled,2,sum) == cmargins)) {
>>          break
>>        }
>>      }
>>    }
>>    shuffled
>> }
>>
>> Example:
>>
>>
>>> a=array(sample(c(0,1),10,replace=TRUE),dim=c(5,2))
>>> a
>>>
>>       [,1] [,2]
>> [1,]    0    1
>> [2,]    1    1
>> [3,]    0    1
>> [4,]    0    1
>> [5,]    1    0
>>
>>> shuffle_matrix(a)
>>>
>>       [,1] [,2]
>> [1,]    0    1
>> [2,]    1    1
>> [3,]    1    0
>> [4,]    0    1
>> [5,]    0    1
>>
>> Best,
>> Finny Kuruvilla
>>
>> *****************************************************************
>> Finny Kuruvilla, MD, PhD
>> Harvard Medical School Fellowship Program in Transfusion Medicine
>> Broad Institute of MIT and Harvard
>> Homepage: http://www.people.fas.harvard.edu/~kuruvill/home/
>>
>>
>> On Fri, 27 Apr 2007, Nick Cutler wrote:
>>
>>
>>> I would like to be able to randomise presence-absence (i.e. binary)
>>> matrices whilst keeping both the row and column totals constant. Is
>>> there a function in R that would allow me to do this?
>>>
>>> I'm working with vegetation presence-absence matrices based on field
>>> observations. The matrices are formatted to have sites as rows and
>>> species as columns. The presence of a species on a site is indicated
>>> with a 1 (absence is obviously indicated with a 0).
>>>
>>> I would like to randomise the matrices many times in order to construct
>>> null models. However, I cannot identify a function in R to do this, and
>>> the programming looks tricky for someone of my limited skills.
>>>
>>> Can anybody help me out?
>>>
>>> Many thanks,
>>>
>>> Nick Cutler
>>>
>>> Institute of Geography
>>> School of Geosciences
>>> University of Edinburgh
>>> Drummond Street
>>> Edinburgh EH8 9XP
>>> United Kingdom
>>>
>>> Tel: 0131 650 2532
>>> Web: http://www.geos.ed.ac.uk/homes/s0455078
>>>
>>> ______________________________________________
>>> R-help at stat.math.ethz.ch mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-help
>>> http://www.R-project.org/posting-guide.html
>>> and provide commented, minimal, self-contained, reproducible code.
>>>
>>>
>>
>> ______________________________________________
>> R-help at stat.math.ethz.ch mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> http://www.R-project.org/posting-guide.html
>> and provide commented, minimal, self-contained, reproducible code.
>>
>>
>>
>
>
> --
> Stéphane DRAY (dray at biomserv.univ-lyon1.fr )
> Laboratoire BBE-CNRS-UMR-5558, Univ. C. Bernard - Lyon I
> 43, Bd du 11 Novembre 1918, 69622 Villeurbanne Cedex, France
> Tel: 33 4 72 43 27 57       Fax: 33 4 72 43 13 88
> http://biomserv.univ-lyon1.fr/~dray/
>

*****************************************************************
Finny Kuruvilla, MD, PhD
Harvard Medical School Fellowship Program in Transfusion Medicine
Broad Institute of MIT and Harvard
Homepage: http://www.people.fas.harvard.edu/~kuruvill/home/
```