如何随机(或置换)一个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")
-
times
是你想要的随机matrix的数量,这里是99 -
burnin
是我们开始随机抽样之前所做的掉期次数。 这使得我们从我们抽样的matrix是非常随机的,然后我们开始采取我们的每个随机matrix -
thin
说只能随便抽取每个thin
掉期 -
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