4

私は次のことをしたいと思います:

データフレームに結合され、2つのベクトルが

  • 長さが違う
  • 他のベクターにも見られる配列を含む
  • 他のベクターにはない配列を含む
  • 他のベクトルにないシーケンスは、3要素より長くなることはありません
  • 常に同じ最初の要素を持っている

データフレームは、整列された2つのベクトルの等しいシーケンスを表示する必要があります。ベクトルに他のベクトルに存在するシーケンスがない場合は、列にNAが表示されます。

例えば:

vector 1    vector 2                     vector 1        vector 2
   1           1                            a               a
   2           2                            g               g
   3           3                            b               b
   4           1            or              h               a
   1           2                            a               g
   2           3                            g               b   
   5           4                            c               h
               5                                            c

データフレームに結合する必要があります

    1   1                                    a   a
    2   2                                    g   g
    3   3                                    b   b
    4   NA                                   h   NA
    1   1                  or                a   a 
    2   2                                    g   g
    NA  3                                    NA  b
    NA  4                                    NA  h
    5   5                                    c   c

私がしたことは、merge、combine、cbind、plyrの例を検索することでしたが、解決策を見つけることができませんでした。この問題を解決するには、ネストされたforループを使用して関数の作成を開始する必要があります。

4

2 に答える 2

6

-これは、OPの最初のバージョンに対する回答として提案されました。それ以来、質問は修正されましたが、私の意見では、問題はまだ明確に定義されていません。


これは、あなたのinteger例で機能し、numericベクトルでも機能するソリューションです。私はまたそれを仮定しています:

  • 両方のベクトルに同じ数のシーケンスが含まれています
  • 新しいシーケンスはどこから始まりますvalue[i+1] <= value[i]

ベクトルが数値でない場合、または私の仮定の1つが問題に適合しない場合は、明確にする必要があります。

v1 <- c(1,2,3,4,1,2,5)
v2 <- c(1,2,3,1,2,3,4,5)

v1.sequences <- split(v1, cumsum(c(TRUE, diff(v1) <= 0)))
v2.sequences <- split(v2, cumsum(c(TRUE, diff(v2) <= 0)))

align.fun <- function(s1, s2) { #aligns two sequences
  s12 <- sort(unique(c(s1, s2)))
  cbind(ifelse(s12 %in% s1, s12, NA),
        ifelse(s12 %in% s2, s12, NA))
}

do.call(rbind, mapply(align.fun, v1.sequences, v2.sequences))
#       [,1] [,2]
#  [1,]    1    1
#  [2,]    2    2
#  [3,]    3    3
#  [4,]    4   NA
#  [5,]    1    1
#  [6,]    2    2
#  [7,]   NA    3
#  [8,]   NA    4
#  [9,]    5    5
于 2012-12-15T21:47:37.157 に答える
3

私はあなたの問題が最短の一般的なスーパーシーケンスの観点から解決されるかもしれないと主張します。2つのベクトルがそれぞれ1つのシーケンスを表すことを前提としています。以下のコードを試してみてください。

それでも問題が解決しない場合は、「私のベクトルには1つではなく多くのシーケンスが含まれている」とはどういう意味かを正確に説明する必要があります。シーケンスの意味を定義し、スキャンしてシーケンスを特定する方法を教えてください。 2つのベクトル。

パートI :2つのシーケンスが与えられた場合、最長共通部分列を見つけます

LongestCommonSubsequence <- function(X, Y) {
    m <- length(X)
    n <- length(Y)
    C <- matrix(0, 1 + m, 1 + n)
    for (i in seq_len(m)) {
        for (j in seq_len(n)) {
            if (X[i] == Y[j]) {
                C[i + 1, j + 1] = C[i, j] + 1
            } else {
                C[i + 1, j + 1] = max(C[i + 1, j], C[i, j + 1])
            }
        }
    }

    backtrack <- function(C, X, Y, i, j) {
        if (i == 1 | j == 1) {
            return(data.frame(I = c(), J = c(), LCS = c()))
        } else if (X[i - 1] == Y[j - 1]) {
            return(rbind(backtrack(C, X, Y, i - 1, j - 1),
                         data.frame(LCS = X[i - 1], I = i - 1, J = j - 1)))
        } else if (C[i, j - 1] > C[i - 1, j]) {
            return(backtrack(C, X, Y, i, j - 1))
        } else {
            return(backtrack(C, X, Y, i - 1, j))
        }
    }

    return(backtrack(C, X, Y, m + 1, n + 1))
}

パートII:2つのシーケンスが与えられた場合、最短の共通スーパーシーケンスを見つけます

ShortestCommonSupersequence <- function(X, Y) {
    LCS <- LongestCommonSubsequence(X, Y)[c("I", "J")]
    X.df <- data.frame(X = X, I = seq_along(X), stringsAsFactors = FALSE)
    Y.df <- data.frame(Y = Y, J = seq_along(Y), stringsAsFactors = FALSE)   
    ALL <- merge(LCS, X.df, by = "I", all = TRUE)
    ALL <- merge(ALL, Y.df, by = "J", all = TRUE)
    ALL <- ALL[order(pmax(ifelse(is.na(ALL$I), 0, ALL$I),
                          ifelse(is.na(ALL$J), 0, ALL$J))), ]
    ALL$SCS <- ifelse(is.na(ALL$X), ALL$Y, ALL$X)
    ALL
}

あなたの例

ShortestCommonSupersequence(X = c("a","g","b","h","a","g","c"),
                            Y = c("a","g","b","a","g","b","h","c"))
#    J  I    X    Y SCS
# 1  1  1    a    a   a
# 2  2  2    g    g   g
# 3  3  3    b    b   b
# 9 NA  4    h <NA>   h
# 4  4  5    a    a   a
# 5  5  6    g    g   g
# 6  6 NA <NA>    b   b
# 7  7 NA <NA>    h   h
# 8  8  7    c    c   c

(2つの更新されたベクトルは列XとにありYます。)

于 2012-12-16T04:15:21.213 に答える