2014-11-27 4 views
1

Этот вопрос является дополнением к this. Я думал, что дополнительное условие было достаточно существенным, чтобы создать новый вопрос.Инкремент с несколькими условиями

У меня есть dataframe date s и event s, как показано ниже.

data <- data.frame(date= as.Date(c(rep("24.07.2012",12), rep("25.07.2012",8)), format="%d.%m.%Y"), 
        event=rep(0,20) ) 
data$event[10] <- 1 
data$event[15] <- 1 

Хочу добавить start счетчик столбец, который увеличивает в 10-х и сброса:

  • 1) сразу после события = 1 наблюдается.
  • 2), когда дата изменилась с предыдущей строки.

Таким образом, желаемый результат с этим дополнительным start колонки будет:

  date event start 
1 2012-07-24  0  0 
2 2012-07-24  0 10 
3 2012-07-24  0 20 
4 2012-07-24  0 30 
5 2012-07-24  0 40 
6 2012-07-24  0 50 
7 2012-07-24  0 60 
8 2012-07-24  0 70 
9 2012-07-24  0 80 
10 2012-07-24  1 90 
11 2012-07-24  0  0 
12 2012-07-24  0 10 
13 2012-07-25  0  0 
14 2012-07-25  0 10 
15 2012-07-25  1 20 
16 2012-07-25  0  0 
17 2012-07-25  0 10 
18 2012-07-25  0 20 
19 2012-07-25  0 30 
20 2012-07-25  0 40 

linked question имеет очень хорошие решения, которые обслуживают только для условия .

С добавлением условия 2, нам нужно отслеживать значение date для строки (n-1)th. Поэтому я предполагаю, что это усложняет решение.

Любые идеи для решения этой проблемы без петли for?

ответ

4
library(data.table) 
setDT(data) 
data[, start := 10 * (seq_along(event) - 1), 
    by=list(date, cumsum(c(1L, diff(event) == -1L)))] 
#turn the data.table into a data.frame: 
class(data) <- "data.frame" 

Как @David Arenburg напоминает мне, есть setDF теперь, что делает по существу то же самое, и некоторые дополнительные очистки.

data 
#   date event start 
#1 2012-07-24  0  0 
#2 2012-07-24  0 10 
#3 2012-07-24  0 20 
#4 2012-07-24  0 30 
#5 2012-07-24  0 40 
#6 2012-07-24  0 50 
#7 2012-07-24  0 60 
#8 2012-07-24  0 70 
#9 2012-07-24  0 80 
#10 2012-07-24  1 90 
#11 2012-07-24  0  0 
#12 2012-07-24  0 10 
#13 2012-07-25  0  0 
#14 2012-07-25  0 10 
#15 2012-07-25  1 20 
#16 2012-07-25  0  0 
#17 2012-07-25  0 10 
#18 2012-07-25  0 20 
#19 2012-07-25  0 30 
#20 2012-07-25  0 40 
+0

Спасибо @Roland. В конце операции 'class (data) [1]" data.table "" data.frame "', я могу продолжить обработку 'data' как dataframe после этой операции или мне нужно' as.data.frame() '. Причина, по которой я спрашиваю, - это «данные» в действительности, это примерно '5M rows * 69cols', так что бы преобразование назад и вперед в data.table (при необходимости) вызвало проблемы с производительностью? (Я не знаком с пакетом) – Rhubarb

+1

Я отредактировал свой ответ. Однако с вашим размером данных вы должны работать с data.tables. – Roland

+0

Благодарим вас за советы. Я прочитаю больше о пакете 'data.table'. – Rhubarb

0

Для справки, это некрасиво ответ for петли, что я хочу, чтобы избежать:

# for loop solution 
data$start_loop <- rep (0, nrow(data)) 
for (r in 2:nrow(data)) { 
    if((data$event[r-1] == 1) | (data$date[r] != data$date[r-1])){ 
    data$start_loop[r] = 0 
    } 
    else { 
    data$start_loop[r] <- data$start_loop[r-1] + 10 
    } 
} 
Смежные вопросы