2014-11-26 2 views
2

Это должно быть тривиальным код, но не мог думать о шикарном однострочнике в R. У меня есть dataframe, как показано ниже:R - условные инкрементации

data <- data.frame(index= seq(1:20), event=rep(0,20) ) 
data$event[10] <- 1 
data$event[15] <- 1 

Я просто хочу, чтобы добавить start и stop счетчика столбцов что приращение в 10 и сброс сразу после event=1 наблюдается. Таким образом, желаемый результат с этими двумя дополнительными столбцами будет:

index event start stop 
1 1 0  0 10 
2 2 0 10 20 
3 3 0 20 30 
4 4 0 30 40 
5 5 0 40 50 
6 6 0 50 60 
7 7 0 60 70 
8 8 0 70 80 
9 9 0 80 90 
10 10 1 90 100 
11 11 0 0  10 
12 12 0 10 20 
13 13 0 20 30 
14 14 0 30 40 
15 15 1 40 50 
16 16 0 0  10 
17 17 0 10 20 
18 18 0 20 30 
19 19 0 30 40 
20 20 0 40 50 

Очевидно, data$stop <- data$start + 10, но как я могу apply() в start приращением loigc, как описано?

ответ

7

Как об этом:

Reduce(function(x,y) (1-y)*(x+10), data$event[-nrow(data)], accumulate=T, init=0) 
4

Вы можете получить свои значения с

data$start <- 10*(ave(
    rep(0,nrow(data)), 
    cumsum(c(0, head(data$event,-1))), 
    FUN=seq_along)-1 
) 
data$end <- data$start + 10 

Здесь мы используем cumsum, чтобы отслеживать, когда события происходят (но нам нужно перенести их шаг, чтобы сброс происходит после события, а не на мероприятии). И мы используем ave внутри групп для генерации последовательностей для каждой группы.

1

К сожалению, применяемое семейство функций заменяет цикл for только тогда, когда итерации этого цикла не зависят от предыдущих итераций.

Вы можете написать цикл, как:

data <- data.frame(index= seq(1:20), event=rep(0,20) ) 
data$event[10] <- 1 
data$event[15] <- 1 
print(data) 
data$start = rep(0, 20) 
for(i in 2:20){ 
    if(data$event[i] == 1){ 
    data$start[i] = 0 
    } else data$start[i] = data$start[i-1] + 10 
} 
data$stop = data$start+10 
print(data) 
+0

Спасибо @jarfa. Однако я подозреваю, что это будет довольно медленным. (хотя он также подходит для нескольких условий). Я должен был четко указать, что я стараюсь избегать циклов по соображениям производительности. – Rhubarb

+0

Я полагаю, вы предпочтете не использовать цикл for, но я не знал, что есть альтернатива. Функция Reduce() довольно крутая. – jarfa

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