随机分配数据

我有一群人,每个人都提交了一个会议的介绍。 每个演示文稿需要由其他提交者审查7次,但没有提交者应该审查自己的演示文稿。 我想随机分配每个人审查7个演示文稿,每个演示文稿只审查7次,没有人审查自己的。

示例数据:

DT = data.frame(First_Name = letters[1:10], Presentation = 1:10)

我愿意在R或Excel中这样做。 任何帮助表示赞赏。

使用Excel

将该组的成员放在A列中:

在这里输入图像说明

并运行这个macros:

 Sub Reviewers() Dim N As Long, i As Long, j As Long, rA As Range N = Cells(Rows.Count, "A").End(xlUp).Row Set rA = Range("A1:A" & N) ' '----------------------------------PART 1 ' For i = 1 To N j = i + 1 rA.Copy Cells(1, j) Cells(i, j).Delete shift:=xlUp Next i ' '---------------------------------PART 2 ' For i = 2 To N + 1 Call SkrambleRange(Range(Cells(1, i), Cells(N - 1, i))) Next i End Sub Sub SkrambleRange(rng As Range) Dim arr(), r As Range, i As Long ReDim arr(1 To rng.Count) i = 1 For Each r In rng arr(i) = r.Value i = i + 1 Next r Call Shuffle(arr) i = 1 For Each r In rng r.Value = arr(i) i = i + 1 Next r End Sub Public Sub Shuffle(InOut() As Variant) Dim i As Long, j As Long Dim tempF As Double, Temp As Variant Hi = UBound(InOut) Low = LBound(InOut) ReDim Helper(Low To Hi) As Double Randomize For i = Low To Hi Helper(i) = Rnd Next i j = (Hi - Low + 1) \ 2 Do While j > 0 For i = Low To Hi - j If Helper(i) > Helper(i + j) Then tempF = Helper(i) Helper(i) = Helper(i + j) Helper(i + j) = tempF Temp = InOut(i) InOut(i) = InOut(i + j) InOut(i + j) = Temp End If Next i For i = Hi - j To Low Step -1 If Helper(i) > Helper(i + j) Then tempF = Helper(i) Helper(i) = Helper(i + j) Helper(i + j) = tempF Temp = InOut(i) InOut(i) = InOut(i + j) InOut(i + j) = Temp End If Next i j = j \ 2 Loop End Sub 

第1部分为每个提交者生成一个评论者列表。 所以B列是Mary Smith的评论者名单(Mary Smith自己的名字已被删除) ; C列是Patricia Johnson等的评论者名单

第2部分洗牌每个评论者专栏:

在这里输入图像说明

为了得到Mary Smith的7位审稿人,从B栏中取出前7个名字。
为了得到帕特里夏·约翰逊的7个评论者,从C列中拉出前7个名字,等等。

R的igraph库有随机图生成algorithm。 这听起来像是你想把每个人随机地连接到另外7个人,比如说一个10人的团队。 这可以表示为具有10个顶点的图,每个顶点具有7度。

图书馆里有一个这样的方法

 library(igraph) plot(g <- sample_degseq(rep(7,10),method="vl")) 

在这里输入图像说明

这是一个使用线性编程的解决scheme。 (灵感来自随机分配元素重复数量有限的组和https://acoppock.github.io/subpages/Random_Assignment_Subject_To_Constraints.html

 library(lpSolve) library(tidyverse) df <- # get all possible person-presentation combinations expand.grid(person = letters[1:10], presentation = 1:10) %>% mutate(person_number = match(person, letters)) %>% # throw out self-matches filter(presentation != person_number) # Two constraints: # each presentation is reviewed 7 times. # Each person conducts 7 reviews first <- t(sapply(1:10, function(i) as.numeric(df$presentation == i))) second <- t(sapply(letters[1:10], function(i) as.numeric(df$person == i))) const.mat <- rbind(first, second) const.dir <- rep(c("=", "="), c(10, 10)) const.rhs <- rep(c(7, 7), c(10, 10)) # This is the acutal stochastic part random_objective <- runif(ncol(const.mat)) mod <- lp( direction = "max", objective.in = random_objective, const.mat = const.mat, const.dir = const.dir, const.rhs = const.rhs, all.bin = TRUE ) df$assign_review <- mod$solution with(df, table(assign_review)) with(df, table(assign_review, presentation)) with(df, table(assign_review, person)) 

这将产生所需的输出:

 > with(df, table(assign_review, presentation)) presentation assign_review 1 2 3 4 5 6 7 8 9 10 0 2 2 2 2 2 2 2 2 2 2 1 7 7 7 7 7 7 7 7 7 7 > with(df, table(assign_review, person)) person assign_review abcdefghij 0 2 2 2 2 2 2 2 2 2 2 1 7 7 7 7 7 7 7 7 7 7