假设我有

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

如何组合来实现输出向量1 2 33 2 1

相似地

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

期望的输出是1 3 22 3 1

对于我的一生,我无法解决这个问题。

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


4 个回答
4

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

# added `rev()` per OP comment
join_by_common <- function(x, y) {
  c(setdiff(x, y), intersect(x, y), rev(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(4,1,2), c(5,3,2))
# 4 1 2 3 5

4

  • 如果 x = c(4,1,2) 且 y = c(5,3,2) 则输出为 4 1 2 5 3 而不是 4 1 2 3 5


    – 

  • 我可以在这里使用 rev 函数吗?


    – 

  • 是的,请参阅我编辑的答案。


    – 

  • 1
    我建议编辑您的原始帖子以使您的要求更清楚。包括x = c(4,1,2)y = c(5,3,2)示例。


    – 


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


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

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

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

0

你的意思:

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

2

  • 没有。我需要向量在某种意义上反映其自身。 (1,2,3), (3,4,5) –> (1.2.3.4.5) 或 (1,2,4),(3,5,4) –> (1,2,4 ,5,3)


    – 

  • 我不确定你现在描述的是否与上面相同。但这里有一个解决方案,可以按照您想要的方式排列数字。


    – 

除了主题之外,只有示例而没有任何描述,我们无法确定您想要什么,但以下给出的结果与您的每个示例中的结果相同。我们假设以下情况,因为这些对于所示的每个示例都是正确的:

  • 每个输入没有连续的重复项,或者如果有,则每个此类游程应减少到长度为 1 的游程。
  • 公共元素位于每个输入的开头或结尾

首先尝试由连接向量或反转一个或两个给定列表后连接它们组成的建议L。使用rle给定列表从每个列表中删除连续的重复项,并取长度最小的L2组件。L2

如果您想要打印出使用了和的哪个元素,请使用verbose=print第三个参数– 1、2、3 或 4;否则,使用默认值。在下面的示例中,从未使用过和的第四个元素。也许 4 永远不会出现,在这种情况下可以缩短为前 3 个元素。LL2LL2L

f <- function(x, y, verbose = c) {
  rx <- rev(x); ry <- rev(y)
  L <- list(c(x, y), c(x, ry), c(rx, y), c(rx, ry))
  L2 <- lapply(L, \(z) rle(z)$values)
  L2[[verbose(which.min(lengths(L2)))]]
}

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

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

f(c(4,1,2), c(5,3,2)) # c(4,1,2,3,5)

f(c(1,2,3), c(3,4,5)) # c(1,2,3,4,5) 

f(c(1,2,4), c(3,5,4))  # c(1,2,4,5,3)