2017-03-25 19 views
2

私は、被験者(subid)からの複数の応答を持つデータフレームを持っています。試行はカウントアップされ、1つの科目内で開始されます。ここで複数の列に基づく条件付きカウンタ

は、例えば、データフレームです:

subid <- rep(1:2, c(10,10)) 
trial <- rep(1:5, 4) 
response <- rnorm(20, 10, 3) 

df <- as.data.frame(cbind(subid,trial, response)) 
df 

    subid trial response 
1  1  1 3.591832 
2  1  2 8.980606  
3  1  3 12.943185  
4  1  4 9.149388  
5  1  5 10.192392  
6  1  1 15.998124  
7  1  2 13.288248  

私は裁判が一人の被験者のID(サブID)内の上に起動するたびにインクリメント列たい:

df$block <- c(rep(1:2, c(5,5)),rep(1:2, c(5,5))) 
df 
    subid trial response block 
1  1  1 3.591832  1 
2  1  2 8.980606  1 
3  1  3 12.943185  1 
4  1  4 9.149388  1 
5  1  5 10.192392  1 
6  1  1 15.998124  2 
7  1  2 13.288248  2 

試験はどこで予測可能ではありませんがやり直すこれまでの私の解決策は面倒で、forループを利用しています。

ソリューション:

block <- 0 
blocklist <- 0 

for (i in seq_along(df$trial)){ 
    if (df$trial[i]==1){ 
    block = block + 1}else 
    if (df$trial!=1){ 
    block = block} 
    blocklist<- c(blocklist, block) 
} 

blocklist <- blocklist[-1] 
df$block <- blocklist 

このソリューションは、新しいサブIDでオーバー起動しません。私がこれに着く前に、パイプでmutate()とifelse()を使ってWickhamのtidyverseを使用しようとしていました。そのパッケージでこれを達成する方法を誰かが知っていれば、私はそれを感謝します。しかし、私はどのパッケージからでも解決策を使用します。私は約1日前に検索し、これがthisのような他の質問と重複しているとは思わない。

+0

ではいこのたびトライアル== 1をカウントアップだろうが、それは最初からやり直していないでしょうsubidが1から2になったとき –

+0

以下の解決策でそれを更新しました – akrun

+1

ありがとうございます。 –

答えて

2

我々はbase R

df$block <- with(df, ave(trial, subid, FUN = function(x) cumsum(x==1))) 

からaveでこれを行うことができますかdplyr

library(dplyr) 
df %>% 
    group_by(subid) %>% 
    mutate(block = cumsum(trial==1)) 
関連する問題