2016-11-10 3 views
3

以下の構造を持つデータセットがあります。データフレーム内の一連の行にまたがる要素を検索します。

# example data set 

a <- "a" 
b <- "b" 
d <- "d" 

id1 <- c(a,a,a,a,b,b,d,d,a,a,d) 
id2 <- c(b,d,d,d,a,a,a,a,b,b,d) 
id3 <- c(b,d,d,a,a,a,a,d,b,d,d) 

dat <- rbind(id1,id2,id3) 
dat <- data.frame(dat) 

私は繰り返し要素と各列を横切っ最初シーケンスを見つける必要がある「」と直ちにシーケンスを次の要素を識別する。

# desired results 

dat$s3 <- c("b","b","d") 
dat 

は、私が最初のものを3つの段階で問題を打破し、解決することができましたが、私のプログラミングのスキルは非常に限られているとして、私はあなたのアイデアを持っている場合は、手順2と3にアプローチする方法について何かアドバイスをいただければ幸いですそれは他の方法で問題を解決します。それは非常に役立つでしょう。ここで

は、私がこれまで持っているものです:事前に

# Step 1: find the first occurence of "a" in the fist sequence 
dat$s1 <- apply(dat, 1, function(x) match(a,x)) 

# Step 2: find the last occurence in the first sequence 

# Step 3: find the element following the last occurence in the first sequence 

ありがとう!

+0

二重の 'max.col'を使って解決策を試すことができます:簡単に言えば、' a1 = max.col(dat == "a"、 "first") 'は最初に" a "と表示されます。 'dat!=" a "の" cbind(rep(seq_along(a1)、a1)、sequence(a1)) 'インデックスを" a "に置き換え、' dat!= "a" max.col "列インデックス。 –

答えて

2

私が使用したいfilter

fun <- function(x) { 
    x <- as.character(x) 
    isa <- (x == "a") #find "a" values 

    #find sequences with two TRUE values and the last value FALSE 
    ids <- stats::filter(isa, c(1,1,1), sides = 1) == 2L & !isa 

    na.omit(x[ids])[1] #subset  
} 

apply(dat, 1, fun) 
#id1 id2 id3 
#"b" "b" "d" 
+0

ありがとう、テストデータと大規模データの両方で非常にうまくいきます – ZMacarozzi

1

さて、ここで少し厄介である1つの試み、

l1 <- lapply(apply(dat, 1, function(i) as.integer(which(i == a))), 
          function(j) j[cumsum(c(1, diff(j) != 1)) == 1]) 

ind <- unname(sapply(l1, function(i) tail(i, 1) + 1)) 

dat$s3 <- diag(as.matrix(dat[ind])) 

dat$s3 
#[1] "b" "b" "d" 

または機能でそれをラップし、

fun1 <- function(df){ 
    l1 <- lapply(apply(df, 1, function(i) as.integer(which(i == a))), 
       function(j) j[cumsum(c(1, diff(j) != 1)) == 1]) 
    ind <- unname(sapply(l1, function(i) tail(i, 1) + 1)) 
    return(diag(as.matrix(df[ind]))) 
} 

fun1(dat) 
#[1] "b" "b" "d" 
+0

これはテストデータセットで動作します。私は今これと実際の大規模なデータセット上の以前のソリューションをチェックし、うまくいけば、私は本当に助けに感謝、多くのおかげで問題を解決することができるようになります。 – ZMacarozzi

1

は、この(あなたが各行で繰り返されていると仮定)を試してみてくださいです:

library(stringr) 
dat$s3 <-apply(dat, 1, function(x) str_match(paste(x, collapse=''),'aa([^a])')[,2]) 

    X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 s3 
id1 a a a a b b d d a a d b 
id2 b d d d a a a a b b d b 
id3 b d d a a a a d b d d d 
+0

これはテストデータセットで動作します。私はコードのすべての部分を理解していないが、今私は大規模なデータに適用しようとし、それがどのように動作するのを見て、多くのおかげで、本当に助けに感謝します。 – ZMacarozzi

+0

それとも、すべてをベクトル化するだけですか? 'str_match(do.call(paste0、dat)、aa([^ a]) ')[、2]' –

関連する問題