2013-03-22 41 views
3

多对我的人的名单:创建R中

people<-c("Betty", "Joe", "Bob", "Will", "Frank") 

我想随机指定两个人每个人(自赋值是不允许的),我想分配每个人到另一个等量的时间(在上面的例子中,每个人只能被分配给另一个两次)。

因此,例如搭配起来可能是

贝蒂(乔和鲍勃),乔(Bob和威尔),鲍勃(威尔和Frank),威尔(弗兰克和贝蒂)

当然,我中刚刚使用过他们的顺序,但如果这可能是随机的,那将会很好。

任何想法从哪里开始?

回答

3

新(容易)解决方案:使用shift功能从TaRifx包从阿里B.弗里德曼

tt <- sample(people) 
lapply(seq_len(length(tt))-1, function(x) shift(tt, x)[1:3]) 
# if you don't want it to be ordered, just add a sample(.) 
lapply(seq_len(length(tt))-1, function(x) sample(shift(tt, x)[1:3])) 
# [[1]] 
# [1] "Bob" "Frank" "Betty" 
# 
# [[2]] 
# [1] "Frank" "Betty" "Joe" 
# 
# [[3]] 
# [1] "Betty" "Joe" "Will" 
# 
# [[4]] 
# [1] "Joe" "Will" "Bob" 
# 
# [[5]] 
# [1] "Will" "Bob" "Frank" 

(的想法)老办法: 我会走这条路。基本上,一旦你sample “人”,你可以随时,1,2,3,2,3,4,3,4,5,4,5,1。所以,让我们这样做。也就是说,生成这些指标,然后对人们进行抽样并获得三元组。

# generate index 
len <- length(people) 
choose <- 3 # at a time 
idx <- outer(seq(choose), seq(choose+2)-1, '+') 
#  [,1] [,2] [,3] [,4] [,5] 
# [1,] 1 2 3 4 5 
# [2,] 2 3 4 5 6 
# [3,] 3 4 5 6 7 

# sample people 
tt <- sample(people) 
# [1] "Joe" "Will" "Bob" "Frank" "Betty" 
max.idx <- 2*choose + 1 
tt[(len+1):max.idx] <- tt[seq(max.idx-len)] 
# [1] "Joe" "Will" "Bob" "Frank" "Betty" "Joe" "Will" 

tt[idx] 
# [1] "Joe" "Will" "Bob" "Will" "Bob" "Frank" "Bob" "Frank" "Betty" "Frank" 
# [15] "Betty" "Joe" "Betty" "Joe" "Will" 

split(tt[idx], gl(ncol(idx), nrow(idx))) 
# $`1` 
# [1] "Joe" "Will" "Bob" 
# 
# $`2` 
# [1] "Will" "Bob" "Frank" 
# 
# $`3` 
# [1] "Bob" "Frank" "Betty" 
# 
# $`4` 
# [1] "Frank" "Betty" "Joe" 
# 
# $`5` 
# [1] "Betty" "Joe" "Will" 

现在我们可以把所有的功能:

my_sampler <- function(x, choose) { 
    len <- length(x) 
    idx <- outer(seq(choose), seq(choose+2)-1, '+') 
    sx <- sample(x) 
    max.idx <- 2*choose + 1 
    sx[(len+1):max.idx] <- sx[seq(max.idx-len)] 
    split(sx[idx], gl(ncol(idx), nrow(idx))) 
} 
# try it out 
my_sampler(people, 3) 
my_sampler(people, 4) # 4 at a time 

# if you want this and want a non-ordered solution, wrap this with `lapply` and `sample` 

lapply(my_sampler(people, 3), sample) 
+0

但只有4三元返回时,名称的初始向量是5长时间? – 2013-03-22 15:20:27

+0

OP在他的输出中只有4个...所以我认为就是这样。将进行编辑。 – Arun 2013-03-22 15:21:03

+0

嗯,我明白你的意思了。我认为名单上的每个人都应该分配一些朋友,所以没有人会被排除在派对之外! :-) – 2013-03-22 15:23:10

0

有趣的问题。这会让你在中途停下来。缺少的一点就是人们处于同等数量的合作关系中。如果你想随机分配两个人的人,除了自己这个可以在一个衬里像这样实现...

assigns <- lapply(people , function(x) { c(x , sample(people[!(people %in% x)] , 2)) }) 

第一人称将受让人的最后两个将被分配。

assigns 
#[[1]] 
#[1] "Betty" "Bob" "Will" 

#[[2]] 
#[1] "Joe" "Bob" "Frank" 

#[[3]] 
#[1] "Bob" "Betty" "Joe" 

#[[4]] 
#[1] "Will" "Betty" "Joe" 

#[[5]] 
#[1] "Frank" "Will" "Betty"