2015-06-09 4 views
2

Я пытаюсь создать df с новой переменной под названием «epi» (обозначает эпизод) ... которая основана на переменной «days.since.last» , когда значение 'days.since.last' больше, чем 90, я хочу, чтобы переменная эпизод увеличится на 1.Создайте новую переменную, основанную на размере значения в другом столбце

Вот оригинал DF

deid session.number days.since.last 
1  1    1    0 
2  1    2    7 
3  1    3    12 
4  5    1    0 
5  5    2    7 
6  5    3    14 
7  5    4    93 
8  5    5    5 
9  5    6    102 
10 12    1    0 
11 12    2    21 
12 12    3    104 
13 12    4    4 

Созданное из

help <- data.frame(deid = c(1, 1, 1, 5, 5, 5, 5, 5, 5, 12, 12, 12, 12), 
        session.number = c(1, 2, 3, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4), 
        days.since.last = c(0, 7, 12, 0, 7, 14, 93, 5, 102, 0, 21, 104, 4)) 

Это выход я надеюсь достичь

deid session.number days.since.last epi 
1  1    1    0 1 
2  1    2    7 1 
3  1    3    12 1 
4  5    1    0 1 
5  5    2    7 1 
6  5    3    14 1 
7  5    4    93 2 
8  5    5    5 2 
9  5    6    102 3 
10 12    1    0 1 
11 12    2    21 1 
12 12    3    104 2 
13 12    4    4 2 

Моей лучшей попытки это ниже код, однако, он не меняет первое значение каждого нового эпизода (они остаются на уровне 0) ...

help$epi <- as.numeric(0) 

tmp <- gapply(help, form = ~ deid, FUN = function(x) 
{  
    spanSeq <- rle(x$days.since.last <= 90)$lengths[rle(x$days.since.last <= 90)$values == TRUE] 
    x$epi[x$days.since.last <= 90] <- rep(seq_along(spanSeq), times = spanSeq) 
    rm(spanSeq) 
    x  
}) 
help2 <- do.call("rbind", tmp) 
rownames(help2)<-c(1:length(help2$deid)) 

Любая помощь очень ценится!

ответ

3

Вы могли бы сделать это с dplyr, как это:

library(dplyr) 
help %>% group_by(deid) %>% mutate(epi = cumsum(ifelse(days.since.last>90,1,0))+1) 


    deid session.number days.since.last epi 
1  1    1    0 1 
2  1    2    7 1 
3  1    3    12 1 
4  5    1    0 1 
5  5    2    7 1 
6  5    3    14 1 
7  5    4    93 2 
8  5    5    5 2 
9  5    6    102 3 
10 12    1    0 1 
11 12    2    21 1 
12 12    3    104 2 
13 12    4    4 2 

По существу, group_by все делает группу для переменной 'Deid. Мы назначаем 1 или 0 для каждого «days.since.last», который составляет более 90. Затем мы создаем новую переменную, которая является суммарной суммой этих 1 и 0. Добавляя один к нему, мы получаем желаемый результат.

+3

'help $ epi <- with (help, ave (days.since.last, deid, FUN = function (x) cumsum (x> 90) +1))' является базовым эквивалентом R, использующим 'ave'. – thelatemail

+0

Блестящий. Спасибо, @jalapic. Ура! – bpace

+0

На самом деле, вы можете избавиться от 'ifelse' в этом - это не нужно - логический' TRUE/FALSE' эквивалентен '1/0' в целочисленной форме в любом случае. – thelatemail

Смежные вопросы