按行和列重新排列数据框

3

有人知道如何对数据框中的所有数据进行随机化吗?我的意思是,我想获得一个新的数据框,其中数据按行和列进行排列,以获得与第一个数据框中相同的数字的随机新数据框。

就像这样:

谢谢!

3个回答

9

只需分别在行数和列数上使用sample(),然后使用来自sample()的结果进行索引。

df <- data.frame(matrix(1:25, ncol = 5))

permDF <- function(x) {
  nr <- nrow(x)
  nc <- ncol(x)
  x[sample(nr), sample(nc)]
}

> permDF(df)
  X3 X4 X2 X1 X5
4 14 19  9  4 24
5 15 20 10  5 25
1 11 16  6  1 21
3 13 18  8  3 23
2 12 17  7  2 22
> permDF(df)
  X1 X2 X4 X3 X5
2  2  7 17 12 22
4  4  9 19 14 24
1  1  6 16 11 21
3  3  8 18 13 23
5  5 10 20 15 25

请注意,这样可以将行和列中的值保持在一起,但是列和行的顺序不同。如果您希望数据集完全随机化,则使用数据框架没有真正简单的方法。我会使用矩阵来完成此操作,但需要更多的工作,就像@DWin所展示的那样。
mat <- matrix(1:25, ncol = 5)
pmat <- mat
set.seed(42)
pmat[] <- mat[sample(length(mat))]
pmat

> pmat
     [,1] [,2] [,3] [,4] [,5]
[1,]   23   11   24   10    5
[2,]   25   21   20    9    8
[3,]    7    3   13    1   18
[4,]   19   12    4   16    2
[5,]   14   17    6   15   22

你可以用与上面稍微不同的索引方式,以同样的方式使用矩阵处理数据框中的数据。
mat[sample(nrow(mat)), sample(ncol(mat))]

> set.seed(42)
> mat[sample(nrow(mat)), sample(ncol(mat))]
     [,1] [,2] [,3] [,4] [,5]
[1,]   15   25    5   10   20
[2,]   14   24    4    9   19
[3,]   11   21    1    6   16
[4,]   12   22    2    7   17
[5,]   13   23    3    8   18

+1. 我已经准备好了完全相同的答案,甚至连函数名都一样!在这里你得要快。 - Simon O'Hanlon
@SimonO101,你现在应该知道只需要“等待”(xkcd/1190)。同时,我本来想建议使用sample(as.matrix(df),prod(dim(df))),但Gavin的方法有一个小优点,就是返回一个数据框。 - Carl Witthoft
1
等一下:Gavin的函数正好做了OP所要求的,而我的诡秘代码会以不同的方式混淆事情。请注意,permDF将一行的所有元素保持在一起,尽管在不同的行和不同的顺序中。因此,这取决于您希望结果有多随机。 - Carl Witthoft
看了你的结果,我开始怀疑我的说法:在列内先进行排列,然后对这些结果进行区块置换,是否会得到与“完整”置换相同的结果。 - IRTFM
@DWin 是的,这只是洗牌行和列,但保持元素在行和列中的位置。如果您需要完全随机化,则您的方法是我会采取的方式 - 我甚至开始编写一个编辑来实现这一点。我会添加一个说明来解释这一点。 - Gavin Simpson

6

使用矩阵来进行操作会更快:

dm <- matrix(1:25, ncol = 5); dm
dm[] <- sample(dm); dm

编辑:这是错误的:“我非常确定先在列上排列,然后在行上排列应该会给你与排列整个向量然后重新调整到原始维度相同的结果。” <\s>

“辛普森方法”将给出不同的结果,可能是所请求的(但如果这是作为模拟工作的一部分进行的话,使用矩阵测试平台会更快):

 dm <- dm[ sample(nrow(dm)), sample( ncol(dm)) ]

+1 给你!我总是忘记在这些情况下使用 [] 的威力。 - Jilber Urbina
这是我在评论中提供的解决方案...教训是不要将其发布为答案 :-( (即使它是错误的答案-至少在@Gavin的示例中,它显然不是完全随机化的序列,正如我在那里指出的那样) - Carl Witthoft
我打算放弃了。不太清楚OP想要什么。我同意在列内进行排列,然后对列进行_en_bloc_置换会得到不同的结果。 - IRTFM

0

NMF包中的randomize函数可能是您要寻找的。

从文档中可以看到:

randomize函数可独立地对类似矩阵的对象中的每列进行排列,以生成可用于置换检验或 bootstrap 分析的随机数据。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接