查找两个不同长度的向量之间的所有组合
Posted
技术标签:
【中文标题】查找两个不同长度的向量之间的所有组合【英文标题】:Find all combinations between two vectors of different length 【发布时间】:2019-11-11 00:40:21 【问题描述】:假设我有两个不同长度的向量x_1
和y_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_all
和y_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
....
【问题讨论】:
【参考方案1】:对您的建议稍作改动即可解决问题:
#Assign same, constant index so the merge function will fill
x_all$index <- 1
y_all$index <- 1
#Merge to get all information
x_y_all <- merge(x_all, y_all, by = "index")
#Delete the index
x_y_all$index <- NULL
【讨论】:
【参考方案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
【讨论】:
【参考方案3】:另一种可能的基本 R 方法是使用索引创建您的 x_all
和 y_all
组合(无需在 combn
中创建许多组合,然后进行子集化),然后交叉连接您的组合:
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)),]
)
【讨论】:
【参考方案4】:这是我的(不优雅的)解决方案:
# 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
【讨论】:
以上是关于查找两个不同长度的向量之间的所有组合的主要内容,如果未能解决你的问题,请参考以下文章