如何通过公共元素组合两个向量?

问题描述 投票:0回答:3

假设我有

vec1 = c(1,2)
vec2 = c(2,3)

如何组合以获得输出向量

1 2 3
3 2 1

同样

vec1 = c(3,1)
vec2 = c(3,2)

所需输出为

1 3 2
2 3 1

我一生都无法解决这个问题。

我尝试过相交和并集组合,但这些似乎都对输出的集合进行排序,我正在寻找一个未排序的输出,如上面的示例 2 所示。 R 中是否有连接公共元素的左连接和右连接选项?我正在尝试实现一个通用函数,我可以传递两个向量(具有公共元素的任意长度),这两个向量将按照上面的方式将两个向量组合起来。

r left-join right-join
3个回答
1
投票

如果我理解你的目标——在中间有共享元素,每个向量的独特元素在两侧——

join_by_common <- function(x, y) {
  c(setdiff(x, y), intersect(x, y), setdiff(y, x))
}

join_by_common(c(1,2), c(2,3))
# 1 2 3

join_by_common(c(3,1), c(3,2))
# 1 3 2

join_by_common(c(9, 2, 8, 4, 6), c(1, 8, 7, 3, 9, 5))
# 2 4 6 9 8 1 7 3 5

1
投票

您的意思是:

unique(c(vec1, vec2))  

[1] 3 1 2

如果顺序很重要,您可能会发现这很有趣

library(devtools)
install_github("mrdwab/SOfun")
library(SOfun)

queue = unique(c(vec2, vec1))
as.numeric(moveMe(queue, "3 after 2"))

[1] 2 3 1

0
投票

在你的标题中你说你们有“共同点”。我们可以找到该公共元素并对向量重新排序,然后将它们连接起来。


下面的代码基于以下假设: 公共元素始终位于向量的头部或尾部。

例如,可以使用递归来列出可能的有序选项

f <- function(v1, v2) {
    key <- intersect(v1, v2)
    k1 <- which(v1 == key)
    k2 <- which(v2 == key)
    if (k1 > 1 && k2 == 1) {
        u <- c(v1, v2[-1])
        list(u, rev(u))
    } else if (k2 > 1 && k1 == 1) {
        Recall(v2, v1)
    } else {
        Recall(v1, rev(v2))
    }
}

你将获得

> f(c(4, 1, 2), c(5, 3, 2))
[[1]]
[1] 4 1 2 3 5

[[2]]
[1] 5 3 2 1 4


> f(c(1, 2), c(2, 3))
[[1]]
[1] 1 2 3

[[2]]
[1] 3 2 1
© www.soinside.com 2019 - 2024. All rights reserved.