R将给定数字序列划分为各种组合

时间:2019-04-27 18:45:47

标签: r

假设我们给出了数字序列:

z=c(1,2,3,4,5)

我想通过以下方式从给定的数字序列创建所有可能的类(大小不同):

1)最简单的情况是当班级大小为1,即所有班级大小相等时。在这种情况下,我们有以下几组:1-2、2-3、3-4和4-5。

2)当一个或多个班级人数等于2时。

a)我们可以拥有1个大小为2的班级,以及其他所有大小为1的班级,如下所示:1-3、3-4和4-5。同样,1-2,2-4和4-5和1-2,2-3和3-5。

b)我们可能还会有2个大小为2的类的案例。 例如:1-3和3-5。

3)当一个班级人数为3而一个班级人数为1时,例如1-4和4-5以及1-2和2-5。

4)最后,我们将遇到一种情况,班级人数为4,即1-5。

请注意,在上述所有情况下,上一类的上限等于下一类的下限(即使班级大小不相等)。

在R中有没有办法做到这一点?任何帮助将不胜感激。谢谢。

1 个答案:

答案 0 :(得分:1)

编辑:使用partition包添加了特定的实现。

它的描述方式,听起来像是一种思考的方式,因为您有5个插槽,它们之间有4个范围(破折号),并且有3个潜在的墙将这些范围与相邻的邻居分隔开。

  | | |
1-2-3-4-5

您可以通过打开所有障碍物来获得所有组合:

   0 0 0
 1-2-3-4-5  
 one with class of sizes of 4

全部关闭:

  | | |
1-2-3-4-5
one case with class sizes of 1
1-2
  2-3
    3-4
      4-5

因此,组合都是从000(0)到111(7)的所有二进制数,总共是8,等于2 ^ n,其中n是壁数,即元素数减去2。 / p>

一种方法可以使用如下伪代码:

  1. 采用元素数量-2 =表示所有解决方案的二进制位数
  2. 对于从0到2 ^(#个元素-2)中的每个数字,请转换为二进制。
  3. 使用1的位置来划分范围。
  4. 显示所有范围。
  5. ...利润!!!

似乎R中至少有一个软件包可以为您解决分区问题。这是使用该操作和tidyverse操作的实现。

library(tidyverse)
partitions::compositions(4) %>% 
  as.matrix() %>%
  as_tibble() %>%
  mutate(position = row_number()) %>%
  gather(combo_num, segment_length, -position) %>%
  filter(segment_length > 0) %>%
  mutate(segment_label = paste0(position, "-", position + segment_length)) %>%
  select(-segment_length) %>%
  spread(position, segment_label)



# A tibble: 8 x 5
  combo_num `1`   `2`   `3`   `4`  
  <chr>     <chr> <chr> <chr> <chr>
1 V1        1-5   NA    NA    NA   
2 V2        1-2   2-5   NA    NA   
3 V3        1-3   2-4   NA    NA   
4 V4        1-2   2-3   3-5   NA   
5 V5        1-4   2-3   NA    NA   
6 V6        1-2   2-4   3-4   NA   
7 V7        1-3   2-3   3-4   NA   
8 V8        1-2   2-3   3-4   4-5