Рассчитать последовательность длины цикла и максимум по идентификатору субъекта

У нас есть данные временных рядов, в которых были измерены повторные наблюдения за несколькими субъектами. Я хотел бы рассчитать количество случаев, когда переменная positive == 1 встречается для каждого субъекта (переменная id).

Вторая цель состоит в том, чтобы определить максимальную длину этих серий последовательных наблюдений, в которых positive == 1. Для каждого предмета, вероятно, будет несколько запусков в течение периода исследования. Вместо того, чтобы подсчитывать максимальное количество последовательных положительных наблюдений на субъекта, я хотел бы рассчитать максимальную продолжительность цикла внутри отдельного цикла.

Вот игрушечный набор данных, который иллюстрирует проблему:

set.seed(1234)
test <- data.frame(id = rep(1:3, each = 10), positive = round(runif(30,0,1)))
test$run <- sequence(rle(test$positive)$lengths)
test$run_positive <- ifelse(test$positive == '0', '0', test$run)
test$episode <- ifelse(test$run_positive == '1', '1', '0')

count(test$episode)
  x freq
1 0   25
2 1    5

Приведенный выше код приближается к ответу на мой первый вопрос, в котором я пытаюсь подсчитать количество положительных эпизодов, однако это не зависит от темы. Это приводит к нежелательному эффекту подсчета последнего наблюдения субъекта № 1 и первого наблюдения субъекта № 2 в одном и том же цикле. Может ли кто-нибудь помочь мне разработать код, чтобы обусловить эту кодировку длины цикла по теме?

Во-вторых, как можно извлечь только максимальную длину прогона для каждого прогона, в котором positive == 1? Я хотел бы добавить дополнительный столбец, в котором записываются только наблюдения, в которых максимальная длина пробега. Для субъекта №1 это будет выглядеть так:

   id positive run run_positive episode max_run
1   1        0   1            0       0       0
2   1        1   1            1       1       0
3   1        1   2            2       0       0
4   1        1   3            3       0       0
5   1        1   4            4       0       0
6   1        1   5            5       0       5
7   1        0   1            0       0       0
8   1        0   2            0       0       0
9   1        1   1            1       1       0
10  1        1   2            2       0       2

Если кто-то может придумать способ сделать это, я был бы очень благодарен.


person Entropy    schedule 07.09.2013    source источник
comment
Я не понимаю вашу максимальную длину пробега для каждого запуска. Каждый прогон имеет одну длину, поэтому максимальная здесь не имеет смысла. По крайней мере, не мне. Например, первый запуск для идентификатора 1, где положительное = 1, имеет длину 5. Внутри идентификатора, в пределах запуска для положительного = 1, вы хотите дополнить длину запуска ведущими нулями?   -  person Henrik    schedule 07.09.2013
comment
Для первого вопроса вы можете попробовать with(test, table(id, positive))   -  person Henrik    schedule 07.09.2013
comment
Извините, если я использовал неправильную терминологию для описания того, что я искал. Вы правы в том, что я хочу «дополнить» длину прогона ведущими нулями. Код, который вы предоставили в своем примере with(test, table(id, positive)), довольно близок. Единственная проблема заключается в том, что он суммирует все прогоны для каждого пациента, тогда как я хотел бы однозначно определить продолжительность каждого прогона по субъекту. Поэтому вместо того, чтобы сообщать, что ID#1 имеет 7 положительных результатов, было бы идеально сказать, что ID#1 имеет 2 серии длин 5 и 2. Затем я хотел бы обернуть этот вывод в test и дополнить его ведущими нулями.   -  person Entropy    schedule 07.09.2013
comment
Извините, если я был неясен, мое предложение относилось только к тому, что я считал первым вопросом: количество случаев, в которых переменная положительное == 1 встречается для каждого субъекта.   -  person Henrik    schedule 07.09.2013


Ответы (1)


Я думаю, что это отвечает на ваш первый вопрос:

aggregate(positive ~ id, data = test, FUN = sum)

  id positive
1  1        7
2  2        4
3  3        4

Это может ответить на ваш второй вопрос, но мне нужно будет увидеть желаемый результат для каждого id для проверки:

set.seed(1234)
test <- data.frame(id = rep(1:3, each = 10), positive = round(runif(30,0,1)))
test$run <- sequence(rle(test$positive)$lengths)
test$run_positive <- ifelse(test$positive == '0', '0', test$run)
test$episode <- ifelse(test$run_positive == '1', '1', '0')

test$group <- paste(test$id*10, test$positive, sep='')

my.seq <- data.frame(rle(test$group)$lengths)
test$first <- unlist(apply(my.seq, 1, function(x) seq(1,x)))
test$last  <- unlist(apply(my.seq, 1, function(x) seq(x,1,-1)))

test$max <- ifelse(test$last == 1 & test$positive==1, test$run, 0)
test

   id positive run run_positive episode group first last max
1   1        0   1            0       0   100     1    1   0
2   1        1   1            1       1   101     1    5   0
3   1        1   2            2       0   101     2    4   0
4   1        1   3            3       0   101     3    3   0
5   1        1   4            4       0   101     4    2   0
6   1        1   5            5       0   101     5    1   5
7   1        0   1            0       0   100     1    2   0
8   1        0   2            0       0   100     2    1   0
9   1        1   1            1       1   101     1    2   0
10  1        1   2            2       0   101     2    1   2
11  2        1   3            3       0   201     1    2   0
12  2        1   4            4       0   201     2    1   4
13  2        0   1            0       0   200     1    1   0
14  2        1   1            1       1   201     1    1   1
15  2        0   1            0       0   200     1    1   0
16  2        1   1            1       1   201     1    1   1
17  2        0   1            0       0   200     1    4   0
18  2        0   2            0       0   200     2    3   0
19  2        0   3            0       0   200     3    2   0
20  2        0   4            0       0   200     4    1   0
21  3        0   5            0       0   300     1    5   0
22  3        0   6            0       0   300     2    4   0
23  3        0   7            0       0   300     3    3   0
24  3        0   8            0       0   300     4    2   0
25  3        0   9            0       0   300     5    1   0
26  3        1   1            1       1   301     1    4   0
27  3        1   2            2       0   301     2    3   0
28  3        1   3            3       0   301     3    2   0
29  3        1   4            4       0   301     4    1   4
30  3        0   1            0       0   300     1    1   0
person Mark Miller    schedule 07.09.2013