7

必ずしも同じ長さではない数字の文字列があります。

0,0,1,2,1,0,0,0

1,1,0,1

2,1,2,0,1,0

これらを R のデータフレームにインポートしました。たとえば、上記の 3 つの文字列は次の 3 つの行を生成します (これを と呼びますdf)。

ここに画像の説明を入力

データを理解するのに役立ついくつかの関数を書きたいと思っています。出発点として-数値ベクトルが与えられた場合-サブベクトルとして含まれる行数を確立xする「プロセス」が必要です。たとえば、 if then 、 if thenおよび if then 。私はこの質問から論理を取り、他のもののいくつかを自分で解決できることを望んでいますが、もっと多くの同様の質問があります.Pxx = c(2,1)P(x) = 2x = c(0,0,0)P(x) = 1x = c(1,3)P(x) = 0

4

2 に答える 2

6

編集: 正規表現の方法は次のようになります。

match.regex <- function(x,data){
  xs <- paste(x,collapse="_")
  dats <- apply(data,1,paste,collapse="_")
  sum(grepl(xs,dats))
}


> match.regex(c(1),dat)
[1] 3
> match.regex(c(0,0,0),dat)
[1] 1
> match.regex(c(1,2),dat)
[1] 2
> match.regex(5,dat)
[1] 0

驚くべきことに、これはここに記載されている他の方法よりも高速であり、小規模なデータセットでも大規模なデータセットでも、以下のソリューションの約 2 倍の速さです。正規表現はかなり最適化されているようです:

> benchmark(matching(c(1,2),dat),match.regex(c(1,2),dat),replications=1000)
                       test replications elapsed relative 
2 match.regex(c(1, 2), dat)         1000    0.15      1.0 
1    matching(c(1, 2), dat)         1000    0.36      2.4 

数値をすぐに取得し、よりベクトル化して機能するアプローチは次のとおりです。

matching.row <- function(x,row){
    nx <- length(x)
    sid <- which(x[1]==row)
    any(sapply(sid,function(i) all(row[seq(i,i+nx-1)]==x)))
}

matching <- function(x,data)
  sum(apply(data,1,function(i) matching.row(x,i)),na.rm=TRUE)

ここでは、最初に、一致させたいベクトルと同じ長さの行にわたってウィンドウを移動するインデックスを持つマトリックスを作成します。これらのウィンドウは、ベクトルに対してチェックされます。このアプローチはすべての行で行われ、TRUE を返す行の合計が必要になります。

> matching(c(1),dat)
[1] 3
> matching(c(0,0,0),dat)
[1] 1
> matching(c(1,2),dat)
[1] 2
> matching(5,dat)
[1] 0
于 2012-12-19T12:54:56.910 に答える
3

applyデータの行に対する関数が必要です。

apply(dat, MARGIN = 1, FUN = is.sub.array, x = c(2,1))

wheredatは data.frameで、より大きなベクトル (実際には data.frame の行) に含まれてis.sub.arrayいるかどうかをチェックする関数です。x

私は利用可能なそのようなis.sub.array機能を認識していないので、ここに私がそれを書く方法があります:

is.sub.array <- function(x, y) {
    j <- rep(TRUE, length(y))
    for (i in seq_along(x)) {
        if (i > 1) j <- c(FALSE, head(j, -1))
        j <- j & vapply(y, FUN = function(a,b) isTRUE(all.equal(a, b)),
                        FUN.VALUE = logical(1), b = x[i])
    }
    return(sum(j, na.rm = TRUE) > 0L)
}

(使用の利点は、正規表現では実行できないベクトルのall.equal比較に使用できることです。)numeric

以下にいくつかの例を示します。

apply(dat, 1, is.sub.array, x = c(1, 2))
# [1]  TRUE FALSE  TRUE
apply(dat, 1, is.sub.array, x = c(0, 0, 0))
# [1]  TRUE FALSE FALSE
apply(dat, 1, is.sub.array, x = as.numeric(c(NA, NA)))
# [1] FALSE  TRUE  TRUE

:all.equalはデータ型に影響されるため、データxと同じ型 (整数または数値) で を使用するように注意してください。

于 2012-12-19T12:36:21.007 に答える