随机分配数据

时间:2016-10-24 13:47:50

标签: r excel

我有一群人分别为会议提交了演示文稿。每个演示文稿需要由其他提交者进行7次审核,但没有提交者应该审核自己的演示文稿。我想随机指派每个人审核7个演示文稿,每个演示文稿仅被审核7次,没有人审核自己的演示文稿。

示例数据:

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

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

3 个答案:

答案 0 :(得分:1)

使用 Excel

将该组的成员放在 A

列中

enter image description here

并运行此宏:

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部分会对每个审核者列进行随机播放。:

enter image description here

要获得Mary Smith的7位评论者,请从 B 列中提取前7个名称。
为了获得Patricia Johnson的7位评论者,请从 C 等。

答案 1 :(得分:0)

R的igraph库具有随机图生成算法。听起来你想要将每个人随机连接到另外7个人,比如一组10个人。这可以表示为具有10个顶点的图形,每个顶点具有7度。

这是库中的一种方法

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

enter image description here

答案 2 :(得分:0)

这是使用线性编程的解决方案。 (受Randomly assign elements repeatedly to a limited number of groupshttps://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 a b c d e f g h i j
            0 2 2 2 2 2 2 2 2 2 2
            1 7 7 7 7 7 7 7 7 7 7