首页 > 解决方案 > 检测两个序列之间的差异

问题描述

我有两个时间序列向量:complete_dataincomplete_data。向量中的数据由 6 个可能的事件组成,这些事件在整个向量中随机发生。原则上两者应该是相同的,因为对于每个事件complete_data,然后将相同的事件添加到incomplete_data。但实际上系统中存在一些异常,并非所有事件complete_data都发送到incomplete_data. 因此complete_data长于incomplete_data。我需要找到两者之间模式的差异并标记它们。我做了一个尝试,但它假设两个向量之间的差异发生在一个块中,而实际上,有各种“缺失事件”分散在incomplete_data.

这是我的尝试:

complete_data <- c('a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c')
dfcomplete <- as.data.frame(complete_data)
incomplete_data <- c('a', 'b', 'c', 'a','c', 'a', 'b', 'a', 'b', 'c')
dfincomplete <- as.data.frame(incomplete_data)

findMatch <- function(complete_data, incomplete_data){

  matching_inorder <- NULL
  matching_reverseorder <- NULL

  for (i in 1:length(complete_data)){
    matching_inorder[i] <- complete_data[i] == incomplete_data[i]
    matching_reverseorder[i] <- rev(complete_data)[i] == rev(incomplete_data)[i]
  }

  is_match <- ifelse(matching_inorder == FALSE & 
                       rev(matching_reverseorder) == FALSE, 'non_match', 'match')
  is_match
}

dfcomplete$is_match_incorrect <- findMatch(dfcomplete$complete_data,
                                 dfincomplete$incomplete_data)

这是我想要得到的:

dfcomplete$expected_output <- c('match', 'match', 'match', 'match', 'non-match', 'match',
                 'match', 'match', 'non_match', 'match', 'match', 'match')

实际上,我的数据比这些示例大得多,在整个向量中散布着许多不同的差异。尽管不一定有太多的差异会使任务变得毫无意义,例如,在一种情况下,complete向量有 320 个数据点,而incomplete向量有 309 个。

任何可以提供的帮助将不胜感激。

标签: r

解决方案


有多种方法可以做到这一点,但这里有一个递归的,其中x假定是一个完整的序列和y不完整的。

compare <- function(x, y) {
  if (length(x) > 0) {
    if (x[1] == y[1]) {
      x[1] <- "match"
      c(x[1], compare(x[-1], y[-1]))
    } else {
      x[1] <- "no match"
      c(x[1], compare(x[-1], y))
    }
  }
}
compare(complete_data, incomplete_data)
# [1] "match"    "match"    "match"    "match"    "no match" "match"   
# [7] "match"    "match"    "no match" "match"    "match"    "match" 

另一个可能更具可读性并使用简单循环的方法是

out <- rep(NA, length(incomplete_data))
gap <- 0
for(i in seq_along(complete_data)) {
  if (complete_data[i] == incomplete_data[i - gap]) {
    out[i] <- "match"
  } else {
    out[i] <- "no match"
    gap <- gap + 1
  }
}
out
# [1] "match"    "match"    "match"    "match"    "no match" "match"   
# [7] "match"    "match"    "no match" "match"    "match"    "match" 

推荐阅读