2017-12-29 16 views
0

以下は私のデータフレームです。行名と列名があります。データフレーム内の連続するゼロの数

 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
    row1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 
    row2 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 

Iは、各行の列の両端の最後の列から連続するゼロ(、に基づいてカラム試験を導出したい。以下は一例である。最初の行は、8人の連続するゼロが存在し、そう試験行の値が第2行の8であるべきで、その結果は、唯一のゼロと1であるべきである。(私は15から考えるとゼロが開始されるまで戻りたい)。

 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 test 
    row1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 8 
    row2 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 1 

これを達成する最良の方法は何ですか?

+0

'c(0、0、0、1、0、0)'の結果はどうなりますか? – PoGibas

+0

それは2であるはずです。 – 221B

+0

あなたはなぜ3でないのか説明できますか? – PoGibas

答えて

4

rleを使用してソリューション:

getConsecZeroRle <- function(x) { 
    foo <- rle(x) 
    foo$lengths[tail(which(foo$values), 1)] 
} 
result <- apply(df[, -1] == 0, 1, function(x) getConsecZeroRle(x)) 
df$test <- as.numeric(result) 
df$test[is.na(df$test)] <- 0 

説明:

使用applyあなたのデータフレームのサブセットを反復します。各行について、連続するゼロの長さを計算し(rle)、tailを使用して最後の値を抽出します。ゼロを持たない行は、NAis.na(df$test)を使用)を生成し、ゼロで置き換えます。


sum用いて溶液:

getConsecZeroSum <- function(x) { 
    x[1:tail(which(!x), 1)] <- FALSE 
    sum(x) 
} 
df$test <- apply(df[, -1] == 0, 1, function(x) getConsecZeroSum(x)) 

説明:

抽出最後FALSE各行の値と(x[1:tail(which(!x), 1)] <- FALSE)を次にからゼロ値をカウントするsumを使用する前にFALSEにすべてを回します終わり。

結果:あなたは、単に等しくない最初の値のインデックスを見つけることができる

#  a 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 test 
# 1 row1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 8 
# 2 row2 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 1 
+0

ここにあります1行しか持たないデータフレーム(いくつかの行の名前とcolnamesを持つ)0 0 0 1 0 0 1 0 0 0 0 0 0 0結果の整数(0)を出力として取得するコードを実行すると、 8. – 221B

+0

@ 221Bあなたのデータに合わせて私の解決策を編集しました – PoGibas

+1

以前は何が問題なのでしょうか? – 221B

1

0(最後列から開始)してから引く1:

df$test2 <- apply(df[,ncol(df):1]==0, 1, which.min) - 1 

df 
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 test2 
#1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0  8 
#2 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0  1 

別の答え:

私はなしでこれを行う方法について興味があったので- 行の上に私は(確かに複雑な)Reduceソリューションを思いついた。ではない私はお勧めソリューションが、私はそれを行う方法があったかどうかを確認するために興味があった1:

iniCol <- setNames(df[,ncol(df)] == 0, as.numeric(df[,ncol(df)] == 0)) 
df$test2 <- Reduce(function(ini, add) {temp <- ifelse(pmin(as.numeric(names(ini)), add==0) == 0, ini, rowSums(cbind(ini, add == 0))) 
             ini <- setNames(temp, pmin(as.numeric(names(ini)), add==0))}, 
        df[,(ncol(df)-1):1], 
        ini = iniCol) 

この背後にある考え方は、列が今まで0したかどうかを追跡するnames属性を使用することです。そうだった場合はカウントを停止し、それ以外の場合はカウントを続行します。

関連する問題