我想在数据帧的给定行 block 之间分别随机地重新排序每一列。行 block 是连续的,如下所示:
mylist=list(1:50,51:52,53:102,103:128,129:154,155:180,181:206,207:232,233:258,259:284,285:310,311:336,337:362,363:388,389:414,415:440,441:466,467:492,493:518,519:544,545:570,571:596,597:622,623:648,649:674,675:700)
假设我有一个名为 dat 的 data.frame。它有 700 行和 50 列。所以基本上,对于这 26 个行 block 中的每一个,我希望其中的每一列都能随机重新排序。
具有较小 data.frame 的示例可能是 A =
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4
5 5 5 5 5
6 6 6 6 6
7 7 7 7 7
8 8 8 8 8
9 9 9 9 9
其中每个行 bin 如下:
mylist=list(1:2,3:6,7:9)
可能导致重新排序的数据帧 B=
1 2 1 1 1
2 1 2 2 2
3 4 3 5 3
4 6 4 3 4
5 5 5 6 5
6 3 6 4 6
8 9 8 7 9
9 7 9 8 8
7 8 7 9 7
谢谢。
最佳答案
这是一种方法。它不需要首先存在名为“A”的data.frame
,并且像 BrodieG 的答案一样,假设“mylist”中没有漏洞或重复。
这将产生一个矩阵,其列数由 Ncol
指定。
Ncol <- 50 # Number of columns
A1 <- seq_along(unlist(mylist, use.names = FALSE))
do.call(rbind, # ^^ Generate a sequence
lapply(mylist, function(x) { # Traverse the list
replicate(Ncol, sample(A1[x])) # Use replicate with sample
}))
此处将其应用于您的小列表:
mylist <- list(1:2,3:6,7:9)
set.seed(1) # to be able to reproduce this answer
Ncol <- 5
A1 <- seq_along(unlist(mylist, use.names = FALSE))
do.call(rbind,
lapply(mylist, function(x) {
replicate(Ncol, sample(A1[x]))
}))
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 2 1 2 2
# [2,] 2 1 2 1 1
# [3,] 3 6 4 5 3
# [4,] 6 4 5 3 4
# [5,] 4 5 6 6 5
# [6,] 5 3 3 4 6
# [7,] 8 7 9 8 9
# [8,] 9 8 7 9 8
# [9,] 7 9 8 7 7
另一个需要考虑的选项是“permute”包中的shuffle
。为此,您创建一个分组变量,就像 Henrik 在他的答案中所做的那样,然后将其用作“ block ”,在其中随机排列给定的值范围。
library(permute)
mylist <- list(1:2,3:6,7:9)
block <- how(blocks = rep(seq_along(mylist), sapply(mylist, length)))
shuffle(length(block$blocks), block)
# [1] 2 1 4 5 3 6 7 9 8
您可以轻松地使用replicate
来获取具有多列的矩阵:
set.seed(1)
replicate(5, shuffle(length(block$blocks), block))
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 1 1 1 2
# [2,] 2 2 2 2 1
# [3,] 5 3 6 4 5
# [4,] 6 5 3 6 4
# [5,] 3 6 4 5 6
# [6,] 4 4 5 3 3
# [7,] 9 8 7 7 9
# [8,] 8 9 9 8 8
# [9,] 7 7 8 9 7
关于对 R 中数据帧中阻塞行之间的随机列进行重新排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22018449/