查找两个不同长度的向量之间的所有组合

时间:2019-06-29 11:54:02

标签: r dataframe vector combinations

假设我有两个长度分别为x_1y_1的向量,如下所示:

x_1 = seq(0,49,2)
y_1 = seq(-90,-51,2)

现在我想找到这两个向量的所有可能的组合,大小为5,因此我这样做:

library(tidyr)
x_all = data.frame(t(rbind(combn(x_1, 5))))
y_all = data.frame(t(rbind(combn(y_1, 5))))

现在我只想将值递增2的组合保留下来:

x_all = x_all[x_all$X2 - x_all$X1 == 2 &
                x_all$X3 - x_all$X2 == 2 &
                x_all$X4 - x_all$X3 == 2 &
                x_all$X5 - x_all$X4 == 2, ]

y_all = y_all[y_all$X2 - y_all$X1 == 2 &
                y_all$X3 - y_all$X2 == 2 &
                y_all$X4 - y_all$X3 == 2 &
                y_all$X5 - y_all$X4 == 2, ]

现在我的问题是

如何合并x_ally_all,以便获得具有这两个集合之间所有可能组合的唯一data.frame

有什么建议吗?

这是我尝试失败的尝试:

# Assign an index to each set
x_all$index = c(1:nrow(x_all))
y_all$index = c(1:nrow(y_all))

# Merge the sets
x_y_all = merge(x_all, y_all, by = 'index', all = TRUE)

输出应如下所示:

X1.x X2.x X3.x X4.x X5.x X1.y X2.y X3.y X4.y X5.y 
 0    2    4    6    8   -90  -88  -86  -84  -82
 0    2    4    6    8   -88  -86  -84  -82  -80
 0    2    4    6    8   -86  -84  -82  -80  -78
....
 2    4    6    8   10   -90  -88  -86  -84  -82
 2    4    6    8   10   -88  -86  -84  -82  -80
 2    4    6    8   10   -86  -84  -82  -80  -78
....

4 个答案:

答案 0 :(得分:2)

对您的建议进行一点更改即可解决问题:

import six
six.moves.input( 'Press the <ENTER> key to continue...' )

答案 1 :(得分:2)

这是获得所需结果的一种更简单的方法(比combn方法更容易记忆)-

library(dplyr)

x_1 = seq(0, 49, 2)
y_1 = seq(-90, -51, 2)

x_all <- sapply(x_1, function(x) {
  seq(x, by = 2, length.out = 5)
}) %>% 
  t() %>% 
  as_tibble() %>% 
  mutate(cj = 1)

y_all <- sapply(y_1, function(x) {
  seq(x, by = 2, length.out = 5)
}) %>% 
  t() %>% 
  as_tibble() %>% 
  mutate(cj = 1)

inner_join(x_all, y_all, by = "cj") %>% 
  select(-cj)

# A tibble: 500 x 10
    V1.x  V2.x  V3.x  V4.x  V5.x  V1.y  V2.y  V3.y  V4.y  V5.y
   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1     0     2     4     6     8   -90   -88   -86   -84   -82
 2     0     2     4     6     8   -88   -86   -84   -82   -80
 3     0     2     4     6     8   -86   -84   -82   -80   -78
 4     0     2     4     6     8   -84   -82   -80   -78   -76
 5     0     2     4     6     8   -82   -80   -78   -76   -74
 6     0     2     4     6     8   -80   -78   -76   -74   -72
 7     0     2     4     6     8   -78   -76   -74   -72   -70
 8     0     2     4     6     8   -76   -74   -72   -70   -68
 9     0     2     4     6     8   -74   -72   -70   -68   -66
10     0     2     4     6     8   -72   -70   -68   -66   -64
# ... with 490 more rows

答案 2 :(得分:2)

使用索引创建x_ally_all组合(无需在combn中创建许多组合然后进行子集设置)然后交叉组合您的组合的另一种可能的基R方法:

x_1 = seq(0,49,2)
y_1 = seq(-90,-51,2)

#creating combinations
x_all <- do.call(rbind, lapply(head(seq_along(x_1), -4L), function(n) x_1[n + 0L:4L]))
y_all <- do.call(rbind, lapply(head(seq_along(y_1), -4L), function(n) y_1[n + 0L:4L]))
#or also 
#x_nc <- length(x_1)-4L
#x_all <- matrix(x_1[t(embed(seq_along(x_1), x_nc)[, x_nc:1L])], ncol=5L)

#cross join
cbind(
    x_all[rep(seq_len(nrow(x_all)), each=nrow(y_all)),],
    y_all[rep(seq_len(nrow(y_all)), times=nrow(x_all)),]
)

答案 3 :(得分:0)

这是我(不太优雅)的解决方案:

# create empty list
    x_all_lst = list()

# put into list the `x_all` data.frame n times based on the number of y_all combinations (here 16)
    for (i in 1:nrow(y_all)) {
      x_all_lst[[i]] = x_all
    }

# merge list
    x_all = do.call(rbind, x_all_lst)

# order list by column
    x_all = x_all[with(x_all, order(X1)), ]

# bind x_all and y_all columns
    x_y_all = cbind(x_all, y_all)

# remove row.names
    row.names(x_y_all) = NULL