我在R中有以下向量.将它们视为数字向量.
x = c(1,2,3,4,...100)
Run Code Online (Sandbox Code Playgroud)
我想根据一些输入数字"局部因子"将这个矢量"本地"随机化.例如,如果位置因子是3,那么前3个元素被采用并随机化,接着是接下来的3个元素,依此类推.有没有一种有效的方法来做到这一点?我知道如果我使用样本,它会混淆整个阵列.提前致谢
Arun不喜欢我的另一个答案是多么低效,所以这里有一些非常快的东西;)
它要求每个只需一个电话来runif()和order(),并且不使用sample()在所有.
x <- 1:100
k <- 3
n <- length(x)
x[order(rep(seq_len(ceiling(n/k)), each=k, length.out=n) + runif(n))]
# [1] 3 1 2 6 5 4 8 9 7 11 12 10 13 14 15 18 16 17
# [19] 20 19 21 23 22 24 27 25 26 29 28 30 33 31 32 36 34 35
# [37] 37 38 39 40 41 42 43 44 45 47 48 46 51 49 50 52 54 53
# [55] 55 57 56 58 60 59 62 63 61 66 64 65 68 67 69 71 70 72
# [73] 75 74 73 76 77 78 81 80 79 84 82 83 86 85 87 89 88 90
# [91] 93 92 91 94 96 95 97 98 99 100
Run Code Online (Sandbox Code Playgroud)
编辑:正如@MatthewLundberg所评论的那样,我用"在x中重复数字"指出的问题可以通过工作轻松克服seq_along(x),这意味着结果值将是指数.所以,它是这样的:
k <- 3
x <- c(2,2,1, 1,3,4, 4,6,5, 3)
x.s <- seq_along(x)
y <- sample(x.s)
x[unlist(split(y, (match(y, x.s)-1) %/% k), use.names = FALSE)]
# [1] 2 2 1 3 4 1 4 5 6 3
Run Code Online (Sandbox Code Playgroud)
这里的瓶颈是运行的调用量sample.只要您的数字不重复,我认为您只需拨打一次电话即可sample完成此操作:
k <- 3
x <- 1:20
y <- sample(x)
unlist(split(y, (match(y,x)-1) %/% k), use.names = FALSE)
# [1] 1 3 2 5 6 4 8 9 7 12 10 11 13 14 15 17 16 18 19 20
Run Code Online (Sandbox Code Playgroud)
把所有东西放在一个函数中(我喜欢scramble@Roland的名字):
scramble <- function(x, k=3) {
x.s <- seq_along(x)
y.s <- sample(x.s)
idx <- unlist(split(y.s, (match(y.s, x.s)-1) %/% k), use.names = FALSE)
x[idx]
}
scramble(x, 3)
# [1] 2 1 2 3 4 1 5 4 6 3
scramble(x, 3)
# [1] 1 2 2 1 4 3 6 5 4 3
Run Code Online (Sandbox Code Playgroud)
为了减少答案(并使其更快),请遵循@ flodel的评论:
scramble <- function(x, k=3L) {
x.s <- seq_along(x)
y.s <- sample(x.s)
x[unlist(split(x.s[y.s], (y.s-1) %/% k), use.names = FALSE)]
}
Run Code Online (Sandbox Code Playgroud)
为了记录,引导包(与基础R一起提供)包括一个permutation.array()用于此目的的函数:
x <- 1:100
k <- 3
ii <- boot:::permutation.array(n = length(x),
R = 2,
strata = (seq_along(x) - 1) %/% k)[1,]
x[ii]
# [1] 2 1 3 6 5 4 9 7 8 12 11 10 15 13 14 16 18 17
# [19] 21 19 20 23 22 24 26 27 25 28 29 30 33 31 32 36 35 34
# [37] 38 39 37 41 40 42 43 44 45 46 47 48 51 50 49 53 52 54
# [55] 57 55 56 59 60 58 63 61 62 65 66 64 67 69 68 72 71 70
# [73] 75 73 74 76 77 78 79 80 81 82 83 84 86 87 85 89 88 90
# [91] 93 91 92 94 95 96 97 98 99 100
Run Code Online (Sandbox Code Playgroud)