It is significantly easier if you can use a matrix (2-dim array).set.seed(2)m <- 0.2d <- c(10, 4)a <- array(sample(prod(d)), dim = d)a# [,1] [,2] [,3] [,4]# [1,] 8 17 14 1# [2,] 28 37 40 26# [3,] 22 38 16 29# [4,] 7 35 3 32# [5,] 34 11 23 4# [6,] 36 33 19 31# [7,] 5 24 30 13# [8,] 39 6 27 25# [9,] 15 10 12 9# [10,] 18 2 21 20(我将再次将种子设置为方便让我展示一些有趣"的东西.)(I'm going to set the seed again to something that conveniently gives me something "interesting" to show.)set.seed(2)ind <- which(runif(d[1]) < m)ind# [1] 1 4 7第一个随机性 runif 与 m 进行比较,并生成可能改变的索引.第二个随机性,下面的 sample,采用这些索引并可能对它们进行重新排序.(在这种情况下,它将1,4,7"重新排序为4,1,7",这意味着可能更改的第三行将保持不变.)The first randomness, runif, is compared against m and generates the indices that may change. The second randomness, sample below, takes those indices and possibly reorders them. (In this case, it reorders "1,4,7" to "4,1,7", meaning the third of the rows-that-may-change will be left unchanged.)a[ind,] <- a[sample(ind),]a# [,1] [,2] [,3] [,4]# [1,] 7 35 3 32 # <-- row 4# [2,] 28 37 40 26# [3,] 22 38 16 29# [4,] 8 17 14 1 # <-- row 1# [5,] 34 11 23 4# [6,] 36 33 19 31# [7,] 5 24 30 13 # <-- row 7, unchanged# [8,] 39 6 27 25# [9,] 15 10 12 9# [10,] 18 2 21 20请注意,这是概率,这意味着 0.2 的概率并不能保证您 20%(甚至任何)的行将被交换.Note that this is probabilistic, which means a probability of 0.2 does not guarantee you 20% (or even any) of the rows will be swapped.(因为我猜你真的想保留你的 3-dim(甚至 n-dim)array,你也许可以使用 aperm 在数组矩阵之间传输.)(Since I'm guessing you'd really like to preserve your 3-dim (or even n-dim) array, you might be able to use aperm to transfer between array <--> matrix.)编辑 1作为 runif 的概率使用的替代方法,您可以使用:As an alternative to a probabilitic use of runif, you can use:ind <- head(sample(d[1]),size=d[1]*m)更接近20%"的目标.由于 d[1]*m 通常不是整数,head 会默默地将数字截断/取舍,因此您将获得价格合适的赢家:最接近达到但不超过您想要的百分比.to get closer to your goal of "20%". Since d[1]*m will often not be an integer, head silently truncates/floors the number, so you'll get the price-is-right winner: closest to but not over your desired percentage.编辑 2一种将 n 维数组转换为矩阵并再次返回的可逆方法.警告:虽然逻辑看起来很可靠,但我的测试只包含了几个数组.A reversible method for transforming an n-dimensional array into a matrix and back again. Caveat: though the logic appears solid, my testing has only included a couple arrays.array2matrix <- function(a) { d <- dim(a) ind <- seq_along(d) a2 <- aperm(a, c(ind[2], ind[-2])) dim(a2) <- c(d[2], prod(d[-2])) a2 <- t(a2) attr(a2, "origdim") <- d a2}反转使用 "origdim" 属性(如果仍然存在);只要您对矩阵的修改没有清除其属性,这就会起作用.(简单的行交换不会.)The reversal uses the "origdim" attribute if still present; this will work as long as your modifications to the matrix do not clear its attributes. (Simple row-swapping does not.)matrix2array <- function(m, d = attr(m, "origdim")) { ind <- seq_along(d) m2 <- t(m) dim(m2) <- c(d[2], d[-2]) aperm(m2, c(ind[2], ind[-2]))}(这两个函数应该多做一些错误检查,比如is.null(d).)(These two functions should probably do some more error-checks, such as is.null(d).)示例运行:set.seed(2)dims <- 5:2a <- array(sample(prod(dims)), dim=dims)快速展示:a[,,1,1:2,drop=FALSE]# , , 1, 1# [,1] [,2] [,3] [,4]# [1,] 23 109 61 90# [2,] 84 15 27 102# [3,] 68 95 83 24# [4,] 20 53 117 46# [5,] 110 62 43 8# , , 1, 2# [,1] [,2] [,3] [,4]# [1,] 118 25 14 93# [2,] 65 21 16 77# [3,] 87 82 3 38# [4,] 92 12 78 17# [5,] 49 4 75 80转型:m <- array2matrix(a)dim(m)# [1] 30 4head(m)# [,1] [,2] [,3] [,4]# [1,] 23 109 61 90# [2,] 84 15 27 102# [3,] 68 95 83 24# [4,] 20 53 117 46# [5,] 110 62 43 8# [6,] 67 47 1 54可逆性证明:identical(matrix2array(m), a)# [1] TRUEEDIT 3, "WRAP UP of all code"创建虚假数据:dims <- c(5,4,2)(a <- array(seq(prod(dims)), dim=dims))# , , 1# [,1] [,2] [,3] [,4]# [1,] 1 6 11 16# [2,] 2 7 12 17# [3,] 3 8 13 18# [4,] 4 9 14 19# [5,] 5 10 15 20# , , 2# [,1] [,2] [,3] [,4]# [1,] 21 26 31 36# [2,] 22 27 32 37# [3,] 23 28 33 38# [4,] 24 29 34 39# [5,] 25 30 35 40(m <- array2matrix(a))# [,1] [,2] [,3] [,4]# [1,] 1 6 11 16# [2,] 2 7 12 17# [3,] 3 8 13 18# [4,] 4 9 14 19# [5,] 5 10 15 20# [6,] 21 26 31 36# [7,] 22 27 32 37# [8,] 23 28 33 38# [9,] 24 29 34 39# [10,] 25 30 35 40# attr(,"origdim")# [1] 5 4 2行的随机交换.我在这里使用了 50%.The random-swapping of rows. I'm using 50% here.pct <- 0.5nr <- nrow(m)set.seed(3)(ind1 <- sample(nr, size = ceiling(nr * pct)))# [1] 2 8 4 3 9(ind2 <- sample(ind1))# [1] 3 2 9 8 4m[ind1,] <- m[ind2,]m# [,1] [,2] [,3] [,4]# [1,] 1 6 11 16# [2,] 3 8 13 18# [3,] 23 28 33 38# [4,] 24 29 34 39# [5,] 5 10 15 20# [6,] 21 26 31 36# [7,] 22 27 32 37# [8,] 2 7 12 17# [9,] 4 9 14 19# [10,] 25 30 35 40# attr(,"origdim")# [1] 5 4 2(注意,我在这里预先制作了 ind1 和 ind2,主要是为了看看内部发生了什么.你可以替换 m[ind2,] 与 m[sample(ind1),] 相同的效果.)(Note that I pre-made ind1 and ind2 here, mostly to see what was going on internally. You can replace m[ind2,] with m[sample(ind1),] for the same effect.)顺便说一句:如果我们改为使用 2 的种子,我们会注意到 2 行 没有交换:BTW: if we had instead used a seed of 2, we would notice that 2 rows are not swapped:set.seed(2)(ind1 <- sample(nr, size = ceiling(nr * pct)))# [1] 2 7 5 10 6(ind2 <- sample(ind1))# [1] 6 2 5 10 7正因如此,我选择了3的种子进行演示.但是,这可能会使事情看起来不起作用.由于缺乏更多的控制代码,sample 并不能确保位置改变:期望随机交换行"可以随机选择将第 2 行移动到第 2 行当然是合理的.例如:Because of this, I chose a seed of 3 for demonstration. However, this may give the appearance of things not working. Lacking more controlling code, sample does not ensure that positions change: it is certainly reasonable to expect that "randomly swap rows" could randomly choose to move row 2 to row 2. Take for example:set.seed(267)(ind1 <- sample(nr, size = ceiling(nr * pct)))# [1] 3 6 5 7 2(ind2 <- sample(ind1))# [1] 3 6 5 7 2第一个随机选择五行,然后将它们随机重新排列成不变的顺序.(我建议如果你想强制它们都是运动,你应该问一个新问题,询问只是强制sample向量改变.em>)The first randomly chooses five rows, and then reorders them randomly into an unchanged order. (I suggest that if you want to force that they are all movements, you should ask a new question asking about just forcing a sample vector to change.)无论如何,我们可以通过第二个函数恢复原始维度:Anyway, we can regain the original dimensionality with the second function:(a2 <- matrix2array(m))# , , 1# [,1] [,2] [,3] [,4]# [1,] 1 6 11 16# [2,] 3 8 13 18# [3,] 23 28 33 38# [4,] 24 29 34 39# [5,] 5 10 15 20# , , 2# [,1] [,2] [,3] [,4]# [1,] 21 26 31 36# [2,] 22 27 32 37# [3,] 2 7 12 17# [4,] 4 9 14 19# [5,] 25 30 35 40在数组的第一个平面中,第1行和第5行不变;在第二个平面中,第 1、2 和 5 行保持不变.五行相同,五行移动(但每行内其他方面不变).In the first plane of the array, rows 1 and 5 are unchanged; in the second plane, rows 1, 2, and 5 are unchanged. Five rows the same, five rows moved around (but otherwise unchanged within each row). 这篇关于在子数组之间移动行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!