【问题标题】:Create samples from the output of a combn function in R, with no repeated elements从 R 中的组合函数的输出创建样本,没有重复的元素
【发布时间】:2020-03-14 03:04:50
【问题描述】:

我正在尝试用 R 解决这个问题:在所有可能的字母组合中,我想随机选择 13 对的样本,条件是不重复任何字母。

我正在尝试以下方法:

x<- LETTERS
combi <- combn(x, 2, FUN = NULL, simplify = FALSE) #combines by 2
fulltable <- data.frame(Reduce(rbind, combi)) #Convert list to dataframe of 2 columns

它给了我 323 种可能的组合:

...
X.316  V  Y
X.317  V  Z
X.318  W  X
X.319  W  Y
X.320  W  Z
X.321  X  Y
X.322  X  Z
X.323  Y  Z

我想选择一个样本 - 让我们称之为 SET1 - 13 对字母(总共有 26 个字母),其中没有重复的字母。 然后,一旦创建了这些对,我想提取另一个具有相同条件的样本,但在这种情况下,不包括 SET1。

期望的结果:

X.1  A  E
X.2  C  H
X.3  B  X
X.4  W  Y
X.5  F  K
…..

直到 X.13 并且没有字母在行或列中重复。

在第二个样本提取中,再次组合具有唯一字母的对,但在这种情况下,不允许以前的组合(即 A E / C H)。 它还应该排除排列,例如 E A / H C。

谢谢 AJS

编辑--------- 这个解决方案对我有用:

test <- LETTERS
ctest <- combn(test, 2, FUN = NULL, simplify = FALSE)
ctabl <- data.frame(Reduce(rbind,ctest))
ctabl$row <- 1:nrow(ctabl)

for (i in 1:nrow(ctabl)){
  sname <- ctabl%>% sample_n(13)
  ctabl <- ctabl %>% subset(!row %in% sname$row)
  print(sname)
}

【问题讨论】:

  • 嗨,欢迎来到 SO!如果您添加了一些您想要的输出的描述,我会很有帮助。例如,您可以发布一个额外的代码面板,显示 SET1 的外观。这会让其他人更容易为您提供帮助。
  • 是的,你是对的,输出应该是一个有 2 列的数据框,每一行都有一个唯一的 par。在行或列中不应重复任何字母。例如:A B / C D / E F ...。等将是一个有效的结果。对于上下文:我正在尝试随机配对我公司中的 + 300 位同事进行网络活动,:)。此活动将每周重复一次,因此我需要排除以前的组合,并且每个同事应该只计算一次。

标签: r unique combn


【解决方案1】:

获得可比较结果的更简单方法,希望对您有所帮助...

> x  <- sample(LETTERS, replace = F)
>  ft <- data.frame(x[1:13],x[14:26])
>  ft
   x.1.13. x.14.26.
1        X        D
2        T        Y
3        P        N
4        Z        I
5        M        E
6        K        V
7        B        J
8        R        O
9        H        C
10       S        L
11       A        W
12       G        Q
13       U        F

> # UPDATE based on comment:  
> # That probably moves the post from primarily being R, to being a math problem 
>  # It depends if you want a comprehensive ste of solutions or a couple unique solutions
>  # Couple unique solutions is easier: 
> x1 <- x[1:13]

x1 <- x[1:13]

x2 <- x[14:26];  df2 <- data.frame(x1,x2); df2
x3 <- x[c(15:26,14)]; df3 <- data.frame(x1,x3); df3
x4 <- x[c(16:26,14:15)]; df4 <- data.frame(x1,x4); df4
x5 <- x[c(17:26,14:16)]; df5 <- data.frame(x1,x5); df5
# .... and so on till x14
# Implemented code 
> x1 <- x[1:13]
> 
> x2 <- x[14:26];  df2 <- data.frame(x1,x2); df2
   x1 x2
1   X  D
2   T  Y
3   P  N
4   Z  I
5   M  E
6   K  V
7   B  J
8   R  O
9   H  C
10  S  L
11  A  W
12  G  Q
13  U  F
> x3 <- x[c(15:26,14)]; df3 <- data.frame(x1,x3); df3
   x1 x3
1   X  Y
2   T  N
3   P  I
4   Z  E
5   M  V
6   K  J
7   B  O
8   R  C
9   H  L
10  S  W
11  A  Q
12  G  F
13  U  D
> x4 <- x[c(16:26,14:15)]; df4 <- data.frame(x1,x4); df4
   x1 x4
1   X  N
2   T  I
3   P  E
4   Z  V
5   M  J
6   K  O
7   B  C
8   R  L
9   H  W
10  S  Q
11  A  F
12  G  D
13  U  Y
> x5 <- x[c(17:26,14:16)]; df5 <- data.frame(x1,x5); df5
   x1 x5
1   X  I
2   T  E
3   P  V
4   Z  J
5   M  O
6   K  C
7   B  L
8   R  W
9   H  Q
10  S  F
11  A  D
12  G  Y
13  U  N
> # .... and so on till x14
> 
> # You may need to write a loop /nested loop to get a comprehensive set
> # logic is - find N, combinations of 2/26 letters, then find the combinations of 13/length(N) those 
> # with the condition that no character is repeated in a single vector of any combination in any df.

【讨论】:

  • 一个很好的解决方案。但是,我现在如何提取另一组 13 对并且没有从这次提取中重复?即没有 X D 对,也没有 D X 对,没有 T Y 或 Y T。但它可能是 X Y,例如,因为它是一个新组合。
  • 刚刚更新了解决方案,其中包含一些独特解决方案但不是一套完整的解决方案,如果您发布完整集的解决方案,如果您开始编写循环,这对 SO 社区来说会很棒/寻找替代解决方案。
  • 我确实找到了一个循环解决方案!结合 mi 初始解决方案、xillian 建议和您提出的循环功能建议来生成所有可能的组合。我将其包含在问题正文中。
【解决方案2】:

对于刚刚添加的附加条件 - 您可以在 sample(LETTERS, replace = F) 之前使用 set.seed 来控制序列并确保不同的 ft。

【讨论】:

    猜你喜欢
    • 2021-04-28
    • 2017-01-30
    • 1970-01-01
    • 2015-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多