jeudi 5 juillet 2018

Generate random pairs of items within a vector in R

Suppose I have a character vector (e.g. myv = ('a', 'b', 'c', 'd', 'e')), I would like to randomly generate n = length(myv) pairs of partner1 - partner2 coming from this vector, knowing that:

  • all items should be 1 time partner1 and 1 time partner2, not more and not less;
  • an item cannot be partner with itself (save value for partner1 and partner2 does not work).

I am not finding an elegant way to do this (e.g. with sample, combn or expand.grid), so I currently use an ugly for loop:

set.seed(11)

myv = letters[1:5]

irand = sample(length(myv), length(myv)) # to randomly select partner1

allpairs = expand.grid(myv, myv)
# remove pairs of the same item
allpairs = allpairs[allpairs[,1]!=allpairs[,2],]

usedpartner2 = c() # to store the partner2 which are already used
mypairs = c() # to store results
for (i in 1:length(myv)) {
  partner1 = myv[irand[i]]
  # the potential partner2 must be different from partner1 and not already used
  candidates = allpairs[allpairs[, 1]==partner1 & !(allpairs[, 2] %in% usedpartner2), 2]
  partner2 = as.character(candidates[sample(length(candidates), 1)])
  usedpartner2 = c(usedpartner2, partner2)
  mypairs = rbind(mypairs, c(partner1, partner2))
}

mypairs
#      [,1] [,2]
# [1,] "b"  "e" 
# [2,] "a"  "b" 
# [3,] "e"  "a" 
# [4,] "d"  "c" 
# [5,] "c"  "d" 




Aucun commentaire:

Enregistrer un commentaire