2017-04-20 75 views
2

讚賞正確方向的答案或點數。計算跨數據子集的可變長度序列的重複次數

- 我有一個數據集,按照組織(ID) - 有一列(試用),指示數據對應的試驗。該值從1重複到某個數字。每個試驗值可以重複一個可變長度(例如,1122234444)。 - 通過試驗值的序列在組內重複。例如,在每個ID中 - 你會經歷一系列的試驗,然後在1處重新開始試驗,然後再次重複序列多次。

我需要知道試驗序列在每個id組中重複了多少次。

期望的輸出是變量「重複」。

「重複」變量應該從1開始並重復,直到序列再次重新啓動到1,它應該移動到2以指示試驗序列在第二次重複。

的最大數量的試驗,IDS和重複的次數總是可變的,但在試驗序列總是去(在可變長度重複)1,2,3,....

id <- sort(rep(c("a", "b"), each = 4, times = 2)) 
trial <- rep(1:2, each = 2 , times = 2) 
repetition <- rep(1:2, each = 4, times = 2) 

df <- data.frame(id, trial, repetition) 

    id trial repetition 
1 a  1   1 
2 a  1   1 
3 a  2   1 
4 a  2   1 
5 a  1   2 
6 a  1   2 
7 a  2   2 
8 a  2   2 
9 b  1   1 
10 b  1   1 
11 b  2   1 
12 b  2   1 
13 b  1   2 
14 b  1   2 
15 b  2   2 
16 b  2   2 
+0

似乎有需要另一列或不同的會計重複爲第1行:1 1實際上不重複任何現有1,所以可以是0。如果第1行:1 1,則看起來第2行:a 1 2,如果重複的含義是重複試驗1.但是我必須猜測,這裏的試驗意味着重複在線性實驗鏈中發生的事情,實際上是一個不同的試驗,重複了相同的刺激。我,我會連續數次試驗,並在另外三列中說明刺激等。 – Chris

回答

1

我假定你的數據看起來是這樣的:

trial=rep(c(1,1,2,2,2,3,4,4,4,4,1,2,2,2,2,2,3,3,3,4,5,5,5,6,6,7,1,1,2,3,3,4,5,6,7,7,7),2) 
id=c(rep("a",length(trial/2)),rep("b",length(trial/2))) 
df=data.frame(id,trial,repetition=numeric(length(trial))) 

然後這個代碼你問了,據我瞭解:

counter=1 
for(i in 1:nrow(df)){ 

    if(i>1){ 
    if(df$id[i-1] != df$id[i]){ 
     counter=1 
    } else { 

     if(df$trial[i-1]>df$trial[i]){ 
     counter=counter+1 
     } 

    } 
    df$repetition[i]=counter 
    }else{ 
    df$repetition[i]=1 
    } 
} 

在我的數據幀中,repetition列已經存在,但是 如果數據幀df還沒有repetition列,這也適用。 如果它還不存在,它將被循環中的代碼添加。

+0

這很好用 - 謝謝!我試圖實現一些類似的東西,以尋找跨行的差異來觸發重置,但一直困擾着一些語法。感謝您向我展示如何做到這一點。 – griffmer

1

這是一個使用dplyrsplitstackshape一起使用的想法。我們首先使用new = cumsum(c(1, diff(trial) != 0))來獲得不同組的數量。然後我們按id,new分組並計數(new1)。我們slice得到每個組的頂部,並使用cumsum(trial == 1)來獲得重複。最後,我們使用splitstackshape函數expandRows,它通過我們從new1獲得的計數來複制行。我們通過整理selectungroup來完成。

library(dplyr) 
library(splitstackshape) 

df %>% 
    mutate(new = cumsum(c(1, diff(trial) != 0))) %>% 
    group_by(id, new) %>% 
    mutate(new1 = n()) %>% 
    slice(1L) %>% 
    group_by(id) %>% 
    mutate(repetition = cumsum(trial == 1)) %>% 
    expandRows('new1') %>% 
    select(-new) %>% 
    ungroup() 
# A tibble: 16 × 3 
#  id trial repetition 
# <fctr> <int>  <int> 
#1  a  1   1 
#2  a  1   1 
#3  a  2   1 
#4  a  2   1 
#5  a  1   2 
#6  a  1   2 
#7  a  2   2 
#8  a  2   2 
#9  b  1   1 
#10  b  1   1 
#11  b  2   1 
#12  b  2   1 
#13  b  1   2 
#14  b  1   2 
#15  b  2   2 
#16  b  2   2 
+0

也可以 - 謝謝!感謝您向我展示圖片,我對圖書館分裂堆棧形狀不熟悉。需要注意的是,此解決方案的時鐘速度比先前的答案快,這對於較大的數據集可能很重要。 – griffmer