如何将数据帧按行和按列随机化(或置换)?


96

我有一个这样的数据框(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列是行名,f1 ... f5行是列名。

为了做sample(df1),我得到一个新的数据帧,其计数与df1相同,为1。因此,在整个数据帧中保留1的计数,但在每一行或每一列中均保留1。

是否可以按行或按列进行随机化?

我想为每列随机分配df1,即每列1的数量保持不变。并且每列至少需要更改一次。例如,我可能会有这样的随机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)的帮助,这是我先前对两列随机分配问题的回答。


您想同时对行列进行置换吗?重读此内容,似乎在第二个示例置换行中没有保持列约束(每列中相同的1)。
加文·辛普森

1
请不要注册多个帐户。我已要求版主给你上一问:使用一个使用此帐户合并
加文·辛普森

Answers:


233

给定R data.frame:

> df1
  a b c
1 1 1 0
2 1 0 0
3 0 1 0
4 0 0 0

按行随机播放:

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

默认情况下,sample()随机重排序作为第一个参数传递的元素。这意味着默认大小是传递的数组的大小。传递参数replace=FALSE(默认值)以sample(...)确保无需替换即可完成采样,从而实现了按行随机播放。

按列随机播放:

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

5
我认为这不是头条评论很有趣,但是比去学习其他软件包要简单得多。几乎所有关于置换的问题都是如此。只需使用SAMPLE()!
垃圾平衡

我是否假设此方法将维护row.names是否正确?
tumultous_rooster13年

在这种情况下,是否有理由使用=超过标准<-?
基督教徒

4
那么,这种情况正在改变的行和列的顺序,但什么OP想不同的是:独立洗牌每一行/列
JelenaČuklina

正是我需要的!
ChuckCottrill

18

这是改编data.frameusing包的另一种方法dplyr

逐行:

df2 <- slice(df1, sample(1:n()))

要么

df2 <- sample_frac(df1, 1L)

按列:

df2 <- select(df1, one_of(sample(names(df1)))) 

10

看看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 是您想要的随机矩阵数,此处为99
  2. burnin是我们开始随机抽样之前进行的掉期数。这样,在我们开始获取每个随机矩阵之前,从中采样的矩阵就可以非常随机
  3. thin说每次thin交换都随机抽奖
  4. mtype = "prab" 表示将矩阵视为存在/不存在,即二进制0/1数据。

有两点需要注意,这不能保证任何列或行都已被随机化,但是如果burnin时间足够长,则很有可能发生这种情况。而且,您可能会绘制超出所需数量的随机矩阵,并丢弃不符合所有要求的矩阵。

您的要求每行具有不同数量的更改,这里也未涵盖。同样,您可以采样比所需更多的矩阵,然后也丢弃不满足此要求的矩阵。


6

您还可以使用randomizeMatrixR包中的函数picante

例:

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"维护列总和,richness维护行总和。尽管主要用于在社区生态系统中将物种存在缺失数据集随机化,但在这里效果很好。

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


4

当然,您可以对每一行进行采样:

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

会随机改写行,因此1每行中的数量不变。进行很小的更改,并且也适用于列,但这对读者来说是一个练习:-P


2
没有任何东西试图实现OP希望施加的约束。
加文·辛普森

2

您还可以使用以下方法在数据框中“采样”相同数量的项目:

nr<-dim(M)[1]
random_M = M[sample.int(nr),]

代替dim(M)[1],您可以使用,nrow(M)这样整个过程就变成了单线:random_M <- M[nrow(M),]
Agile Bean,

1

如果目标是随机地对每一列进行洗牌,则上述某些答案将不起作用,因为这些列被一起洗牌了(这保留了列间的相关性)。其他人则需要安装软件包。然而,存在着一线:

df2 = lapply(df1, function(x) { sample(x) })

0

数据帧中的随机样本和排列如果以矩阵形式转换为data.frame,请使用基本包中的样本函数index = sample(1:nrow(df1),size = 1 * nrow(df1))随机样本和排列

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.