首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在R中,我如何局部地混洗向量的元素

在R中,我如何局部地混洗向量的元素
EN

Stack Overflow用户
提问于 2013-07-14 23:09:04
回答 6查看 10K关注 0票数 6

我在R中有下面的向量,把它们想象成一个数字的向量。

代码语言:javascript
运行
复制
x = c(1,2,3,4,...100)

我想根据一些输入数字“局部性因子”来“局部”地随机化这个向量。例如,如果位置因子是3,则取前3个元素并随机化,然后是接下来的3个元素,依此类推。有没有一种有效的方法来做到这一点?我知道如果我使用sample,它会使整个数组变得混乱。提前感谢

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2013-07-14 23:21:43

一般解决方案:

编辑:正如@MatthewLundberg评论的那样,我指出的“在x中重复数字”的问题可以通过使用seq_along(x)轻松克服,这意味着结果值将是索引。所以,它应该是这样的:

代码语言:javascript
运行
复制
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

老生常谈:

这里的瓶颈是对函数sample的调用量。只要您的数字不重复,我认为您只需以这种方式调用一次sample就可以做到这一点:

代码语言:javascript
运行
复制
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

将所有内容放在一个函数中(我喜欢@Roland‘s中的名称scramble ):

代码语言:javascript
运行
复制
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

要进一步简化答案(并更快地获得答案),请关注@flodel的评论:

代码语言:javascript
运行
复制
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)]
}
票数 7
EN

Stack Overflow用户

发布于 2013-07-15 02:40:29

Arun不喜欢我的另一个答案是多么的低效,所以这里有一些非常快的东西给他。)

它只需要分别调用runif()order()一次,而且根本不使用sample()

代码语言:javascript
运行
复制
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
票数 8
EN

Stack Overflow用户

发布于 2013-07-15 00:08:11

根据记录,boot软件包(随base R一起提供)包含一个仅用于此目的的函数permutation.array()

代码语言:javascript
运行
复制
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
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17640617

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档