如何随机(或置换)一个dataframe的行和列?

我有一个像这样的数据框(df1)。

f1 f2 f3 f4 f5 d1 1 0 1 1 1 d2 1 0 0 1 0 d3 0 0 0 1 1 d4 0 1 0 0 1 

d1 … d4列是rowname,f1 … f5行是列名。

为了做样本(df1),我得到一个新的dataframe,其计数与df1相同。 所以,1的数量对整个dataframe是保留的,而对于每一行或每一列都是保留的。

是有可能做行或列明智的随机化?

我想随机每列df1列,即在每列中1的数量保持不变。 每列至less需要更换一次。 例如,我可能有这样一个随机df2:(注意,每列中的1的计数保持不变,但是每行中的计数是1是不同的。

  f1 f2 f3 f4 f5 d1 1 0 0 0 1 d2 0 1 0 1 1 d3 1 0 0 1 1 d4 0 0 1 1 0 

同样,我也想随机化每行的df1行,即没有。 每一行中的1保持不变,并且每行都需要被改变(但是改变的条目的数量可能不同)。 例如,一个随机df3可能是这样的:

  f1 f2 f3 f4 f5 d1 0 1 1 1 1 <- two entries are different d2 0 0 1 0 1 <- four entries are different d3 1 0 0 0 1 <- two entries are different d4 0 0 1 0 1 <- two entries are different 

PS。 非常感谢加文·辛普森(Gavin Simpson),乔里斯·米斯(Joris Meys)和蔡斯(Chase)对于我之前关于随机化两列的问题的回答。

    给定R data.frame:

     > df1 abc 1 1 1 0 2 1 0 0 3 0 1 0 4 0 0 0 

    顺序排列:

     > df2 <- df1[sample(nrow(df1)),] > df2 abc 3 0 1 0 4 0 0 0 2 1 0 0 1 1 1 0 

    默认情况下, sample()随机重新排列作为第一个parameter passing的元素。 这意味着默认大小是传递数组的大小。 将参数replace=FALSE (缺省值)传递给sample(...)可确保采样完成,而不需要进行replace,从而实现了行方式的混洗。

    按列顺序洗牌:

     > df3 <- df1[,sample(ncol(df1))] > df3 cab 1 0 1 1 2 0 1 0 3 0 0 1 4 0 0 0 

    看看纯素包中的permatswap() 。 下面是一个维护行和列总计的例子,但是您可以放松一下,只修复行或列总和中的一个。

     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") 

    这给了:

     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 

    解释电话:

     out <- permatswap(mat, times = 99, burnin = 20000, thin = 500, mtype = "prab") 
    1. times是你想要的随机matrix的数量,这里是99
    2. burnin是我们开始随机抽样之前所做的掉期次数。 这使得我们从我们抽样的matrix是非常随机的,然后我们开始采取我们的每个随机matrix
    3. thin说只能随便抽取每个thin掉期
    4. mtype = "prab"表示将matrix视为存在/不存在,即二进制0/1数据。

    有几件事需要注意,这并不能保证任何列或行都被随机化了,但是如果burnin足够长的话,发生这种事情的机会应该很大。 此外,您可以绘制比您需要的更多的随机matrix,并丢弃不符合您所有要求的matrix。

    您的要求每行有不同数量的更改,也不包括在这里。 再次,你可以抽取更多的matrix比你想要的,然后丢弃那些不符合这个要求也。

    你也可以在R包picante使用randomizeMatrix函数

    例:

     test <- matrix(c(1,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0),nrow=4,ncol=4) > test [,1] [,2] [,3] [,4] [1,] 1 0 1 0 [2,] 1 1 0 1 [3,] 0 0 0 0 [4,] 1 0 1 0 randomizeMatrix(test,null.model = "frequency",iterations = 1000) [,1] [,2] [,3] [,4] [1,] 0 1 0 1 [2,] 1 0 0 0 [3,] 1 0 1 0 [4,] 1 0 1 0 randomizeMatrix(test,null.model = "richness",iterations = 1000) [,1] [,2] [,3] [,4] [1,] 1 0 0 1 [2,] 1 1 0 1 [3,] 0 0 0 0 [4,] 1 0 1 0 > 

    选项null.model="frequency"保持列总和null.model="frequency" richness保持行总和。 虽然主要用于社区生态学中的物种存在缺失数据集的随机化,但在这里运作良好。

    该函数还有其他的null模型选项,查看picante文档的更多详细信息(第36页)的以下链接

    当然,你可以抽样每一行:

     sapply (1:4, function (row) df1[row,]<<-sample(df1[row,])) 

    会自行sorting,因此每行中1的数目不会改变。 小的变化,对列也很好,但是这是读者的一个练习:-P