因此,我想要的是一个数据框,其中行表示两个随机向量的组合。我不想要重复的组合; 1,2;2,1。只有其中 1 个。以及不 self 重复的组合; 1,1.
现在我得到了这个简单的 for 循环,但它并不理想;
unique_combos <- function(v1, v2) {
df <- data.frame(matrix(ncol=2))
counter = 0
for (name1 in v1) {
for (name2 in v2) {
if (name1 != name2){
counter = counter + 1
df[counter,] <- c(name1, name2)
}
}
}
return(df)
}
# example usage;
> v1 <- c(1,2,3,4)
> v2 <- c(3,4,5,6)
> unique_combos(v1, v2)
X1 X2
1 1 3
2 1 4
3 1 5
4 1 6
5 2 3
6 2 4
7 2 5
8 2 6
9 3 4
10 3 5
11 3 6
12 4 3
13 4 5
14 4 6
>
有什么矢量化的方法可以做到这一点?最好也针对性能。 除此之外,我想指出的是,向量可以是任意长度,并且将包含随机变量。
Edit1 - 我的函数不能正常工作!;我不想要 3-4 4-3 组合。
Edit2 - @Ryan 和@Frank 的最终解决方案(谢谢你们!);
unique_combos <- function(v1, v2) {
intermediate <- unique(CJ(v1, v2)[V1 > V2, c("V1", "V2") := .(V2, V1)])
return(intermediate[V1 != V2])
*注意;这确实使用了包 data.table
和 plyr
。
最佳答案
此处的速度差异可能不会产生任何实际影响,除非您的向量很大,但由于您将“性能”作为标签,这里有一个稍微快一些的方法。
library(data.table)
CJ(v1, v2)[V1 != V2]
基准:
注意:
CJ
默认会按v1
排序,在unique_combos2
中按v1
排序比较耗时,所以我删除了那部分,因为不清楚您是否需要它。
unique_combos2 <- function(v1, v2) {
e <- expand.grid(v1, v2)
e <- e[e[[1]] != e[[2]], ]
e
}
unique_combos3 <- function(v1, v2) CJ(v1, v2)[V1 != V2]
w1 <- sample(200)
w2 <- sample(200)
mb2 <- microbenchmark(
u2 = unique_combos2(w1, w2),
u3 = unique_combos3(w1, w2)
)
# Unit: milliseconds
# expr min lq mean median uq max neval cld
# u2 5.513842 5.942765 10.969386 6.692507 8.158763 368.180211 100 b
# u3 1.140513 1.443076 1.898202 1.711384 2.139075 8.397942 100 a
编辑:要删除重复对而不考虑顺序,请在注释中使用@Frank 的解决方案,它在调用 unique
unique(CJ(v1, v2)[V1 > V2, c("V1", "V2") := .(V2, V1)])
关于R - 是否有一种矢量化方式/预制函数可以快速生成两个向量之间的唯一集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52671449/