我的整数模式为c(1,2,3,4,5)
,需要在数据中大致匹配c(1,10,1,6,3,4,5,1,2,3,4,5,9,10,1,2,3,4,6)
我试过了:
但他们似乎不支持这种情况。
pattern <- c(1,2,3,4,5)
data <- c(1,10,1,6,3,4,5,1,2,3,4,5,9,10,1,2,3,4,6)
对于上面的例子,我需要产生以下输出:
1,6,3,4,5
1,2,3,4,5
1,2,3,4,6
感谢对此的任何想法。
由于
答案 0 :(得分:2)
我认为你说“匹配整数的另一个整数序列中的整数序列,其中至少N-1个整数匹配”。目前还不清楚在重叠匹配的情况下应该采取什么行为,因此以下内容将选择重叠的序列。
# helper function to test "match" at a threshold of 4 matches
is_almost <- function(s1, s2, thresh = 4) {
sum(s1 == s2) >= thresh }
# function to lookup and return sequences
extract_seq <- function(pattern, data) {
res <- lapply(1:(length(data) - length(pattern) + 1), function(s) {
subseq <- data[s:(s+length(pattern)-1)]
if (is_almost(pattern, subseq)) {
subseq}
})
Filter(Negate(is.null),res)
}
# let's test it out
pattern <- c(1,2,3,4,5)
data <- c(1,10,1,6,3,4,5,1,2,3,4,5,9,10,1,2,3,4,6)
extract_seq(pattern,data)
[[1]]
[1] 1 6 3 4 5
[[2]]
[1] 1 2 3 4 5
[[3]]
[1] 1 2 3 4 6
答案 1 :(得分:0)
如果您想在向量中找到与给定向量匹配的唯一元素,可以使用%Iin%
来测试您的&#39;模式的存在。在更大的向量内。运算符%in%
返回逻辑向量。将该输出传递给which()
会返回每个TRUE
值的索引,该索引可用于对较大的向量进行子集化,以返回与“&#39;模式”匹配的所有元素,而不管顺序如何。将子集向量传递给unique()
可以消除重复,从而只有一个元素出现在较大的向量中,与元素和模式的长度相匹配。矢量。
例如:
> num.data <- c(1, 10, 1, 6, 3, 4, 5, 1, 2, 3, 4, 5, 9, 10, 1, 2, 3, 4, 5, 6)
> num.pattern.1 <- c(1,6,3,4,5)
> num.pattern.2 <- c(1,2,3,4,5)
> num.pattern.3 <- c(1,2,3,4,6)
> unique(num.data[which(num.data %in% num.pattern.1)])
[1] 1 6 3 4 5
> unique(num.data[which(num.data %in% num.pattern.2)])
[1] 1 3 4 5 2
> unique(num.data[which(num.data %in% num.pattern.3)])
[1] 1 6 3 4 2
请注意,第一个结果符合num.pattern.1
的顺序。其他两个向量与模式向量的顺序不匹配。
要在num.data
中找到与模式匹配的确切序列,您可以使用类似于以下函数的内容:
set.seed(12102015)
test.data <- sample(c(1:99), size = 500, replace = TRUE)
test.pattern.1 <- test.data[90:94]
find_vector <- function(test.data, test.pattern.1) {
# List of all the vectors from test.data with length = length(test.pattern.1), currently empty
lst <- vector(mode = "list")
# List of vectors that meet condition 1, currently empty
lst2 <- vector(mode = "list")
# List of vectors that meet condition 2, currently empty
lst3 <- vector(mode = "list")
# A modifier to the iteration variable used to build 'lst'
a <- length(test.pattern.1) - 1
# The loop to iterate through 'test.data' testing for conditions and building lists to return a match
for(i in 1:length(test.data)) {
# The list is build incrementally as 'i' increases
lst[[i]] <- test.data[c(i:(i+a))]
# Conditon 1
if(sum(lst[[i]] %in% test.pattern.1) == length(test.pattern.1)) {lst2[[i]] <- lst[[i]]}
# Condition 2
if(identical(lst[[i]], test.pattern.1)) {lst3[[i]] <- lst[[i]]}
}
# Remove nulls from 'lst2' and 'lst3'
lst2 <- lst2[!sapply(lst2, is.null)]
lst3 <- lst3[!sapply(lst3, is.null)]
# Return the intersection of 'lst2' and 'lst3' which should be a match to the pattern vector.
return(intersect(lst2, lst3))
}
为了重现性,我使用了set.seed()
,然后创建了一个测试数据集和模式。函数find_vector()
有两个参数:第一个是test.data
,它是你希望检查模式向量的较大数值向量,第二个是test.pattern.1
,它是你希望在中找到的较短数值向量test.data
。首先,创建三个列表:lst
以保持test.data
分为长度等于模式向量长度的较小向量lst2
来保存来自lst
的模式向量满足第一个条件,lst3
保持lst
满足第二个条件的向量。第一个条件测试lst
中向量的元素是否在模式向量中。第二个条件测试来自lst
的向量按顺序和按元素匹配模式向量。
这种方法的一个问题是,当条件不满足时,NULL
值被引入每个列表,但是当条件满足时,过程停止。作为参考,您可以打印列表以查看所有测试的矢量,满足第一个条件的矢量以及满足第二个条件的矢量。可以删除空值。删除空值后,找到lst2
和lst3
的交集将显示test.data
中相同匹配的模式。
要使用此功能,请务必明确定义test.data <- 'a numeric vector'
和test.pattern.1 <- 'a numeric vector'
。不需要特殊包装。我没有进行任何基准测试,但该功能似乎运行得很快。我也没有寻找函数失败的场景。