2017-03-25 66 views
2

我有一個數據框,其中有多個來自主題(subid)的響應,這些響應位於標記爲試驗的列中。試驗計數並在一個主題內重新開始。R基於多列的條件計數器

下面是一個例子數據框:

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(子編號)內開始在列:

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 

這種解決方案並不在一個新的子編號開始。在我來到這之前,我試圖在管道中使用Wickham的mutate()和ifelse()。如果有人知道一種方法來完成這個包,我將不勝感激。不過,我會使用任何軟件包中的解決方案。我已經搜索了大約一天,並且不認爲這是對this等其他問題的重複問題。

+0

是的,這將每次試驗== 1計數,但它不會重新開始當subid從1變爲2. –

+0

在下面的解決方案中更新了 – akrun

+1

謝謝,完美地工作。 –

回答

2

我們可以從avebase R

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

做到這一點還是與dplyr

library(dplyr) 
df %>% 
    group_by(subid) %>% 
    mutate(block = cumsum(trial==1))