计算跨数据子集的可变长度序列的重复

时间:2017-04-20 23:30:20

标签: r

赞赏正确方向的答案或要点。

- 我有一个按组(id)组织的数据集 - 有一列(试验)表示数据对应的试验。该值从1到某个数字重复。每个试验值可以重复可变长度(例如,1122234444)。 - 在组内重复通过试验值的序列。例如,在每个id中 - 你经历一系列试验,然后在1处重新开始试验并再次经历序列多次。

我需要知道在每组id中重复试验序列的次数。

所需的输出是变量“重复”。

“重复”变量应从1开始并重复,直到序列再次重新开始为1,其中它应移至2以指示试验序列在其第二次重复上。

试验的最大数量,ID和重复次数总是可变的,但试验顺序总是变化(以可变长度重复)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

2 个答案:

答案 0 :(得分: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列,这也适用。 如果它还不存在,它将被循环中的代码添加。

答案 1 :(得分:1)

以下是dplyrsplitstackshape一起使用的想法。我们首先使用new = cumsum(c(1, diff(trial) != 0))来获取不同组的数量。然后,我们按idnew分组并计算它们(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