R: рекомендация о том, как вычислять новые столбцы при нескольких условиях других для каждой строки в data.frame

Для каждой записи в строках мне нужно вычислить две переменные как новые столбцы в data.frame в зависимости от более чем 60 других столбцов. Мне бы хотелось, чтобы вы порекомендовали, как реализовать этот элегантный (пока и для, с, если еще, foreach, by или ddply?). Мне не нравится делать это вручную, как я делал в первых случаях в примере кода, и меня не волнует производительность.

Далее: Наверное, мне не нужно было бы спрашивать, понял бы я, как использовать такие функции, как преобразование (с помощью ddply или by) и что они делают. Таким образом, я надеюсь, что вы можете порекомендовать хорошие учебники по этому вопросу, возможно, относящиеся к моему делу. Я нашел многое, но в другом контексте, и не смог полностью понять или расшифровать это для своего случая.

Мой случай: у меня есть три столбца для каждого из 20 событий, представляющих тип и дату этого события. Для каждой строки мне нужно вычислить (и сохранить в этом data.frame) разницу во времени между одним особым событием (в зависимости от того, произошло ли особое событие до или после другого) и датой, фиксированной для каждой записи в строках. Кроме того, мне нужно сохранить дату этого события.

Вот как я это сделал (работает, но работает только в первых случаях):

#event.2 (1. event month), event.3 (1. event year), event.4 (1. event kind), event.5 (2. event month), event.6 (2. event year), ...

df$dit[(!is.na(df$event.2) & !is.na(df$event.3) & !is.na(df$event.4) & !is.na(df$event.5) & !is.na(df$event.6) & !is.na(df$event.7)) 
             & ( 
               (df$event.4 == 3 & ((1/12*df$event.2)+df$event.3) > df$fixdate) & (df$event.7 == 1 | df$event.7 == 2)
               )] = ((1/12*df$event.2)+df$event.3) - df$fixdate
df$date[(!is.na(df$event.2) & !is.na(df$event.3) & !is.na(df$event.4) & !is.na(df$event.5) & !is.na(df$event.6) & !is.na(df$event.7)) 
             & ( 
               (df$event.4 == 3 & ((1/12*df$event.2)+df$event.3) > df$fixdate) & (df$event.7 == 1 | df$event.7 == 2)
             )] = ((1/12*df$event.2)+df$event.3)

df$dit[(!is.na(df$event.2) & !is.na(df$event.3) & !is.na(df$event.4) & !is.na(df$event.5) & !is.na(df$event.6) & !is.na(df$event.7))
             & ( 
                 (df$event.4 == 1 & ((1/12*df$event.2)+df$event.3) > df$fixdate)
               | (df$event.4 == 2 & ((1/12*df$event.2)+df$event.3) > df$fixdate)
               )] = 0
df$date[(!is.na(df$event.2) & !is.na(df$event.3) & !is.na(df$event.4) & !is.na(df$event.5) & !is.na(df$event.6) & !is.na(df$event.7))
             & ( 
               (df$event.4 == 1 & ((1/12*df$event.2)+df$event.3) > df$fixdate)
               | (df$event.4 == 2 & ((1/12*df$event.2)+df$event.3) > df$fixdate)
             )] = df$fixdate

df$dit[(!is.na(df$event.2) & !is.na(df$event.3) & !is.na(df$event.4) & !is.na(df$event.5) & !is.na(df$event.6) & !is.na(df$event.7)) 
             & ( 
                (
                    (df$event.4 == 1 & ((1/12*df$event.2)+df$event.3) < df$fixdate)
                  & (  
                      (df$event.7 == 1 & ((1/12*df$event.5)+df$event.6) > df$fixdate)
                    | (df$event.7 == 2 & ((1/12*df$event.5)+df$event.6) > df$fixdate)
                    )
                )
               | 
                (
                     (df$event.4 == 2 & ((1/12*df$event.2)+df$event.3) < df$fixdate)
                   & (  
                       (df$event.7 == 1 & ((1/12*df$event.5)+df$event.6) > df$fixdate)
                     | (df$event.7 == 2 & ((1/12*df$event.5)+df$event.6) > df$fixdate)
                     )
                )
              )] = ((1/12*df$event.5)+df$event.6) - df$fixdate
df$date[(!is.na(df$event.2) & !is.na(df$event.3) & !is.na(df$event.4) & !is.na(df$event.5) & !is.na(df$event.6) & !is.na(df$event.7)) 
             & ( 
               (
                 (df$event.4 == 1 & ((1/12*df$event.2)+df$event.3) < df$fixdate)
                 & (  
                   (df$event.7 == 1 & ((1/12*df$event.5)+df$event.6) > df$fixdate)
                   | (df$event.7 == 2 & ((1/12*df$event.5)+df$event.6) > df$fixdate)
                 )
               )
               | 
                 (
                   (df$event.4 == 2 & ((1/12*df$event.2)+df$event.3) < df$fixdate)
                   & (  
                     (df$event.7 == 1 & ((1/12*df$event.5)+df$event.6) > df$fixdate)
                     | (df$event.7 == 2 & ((1/12*df$event.5)+df$event.6) > df$fixdate)
                   )
                 )
             )] = ((1/12*df$event.5)+df$event.6)

person Schirnhaden    schedule 29.11.2013    source источник
comment
Привет и добро пожаловать в stackoverflow! Гораздо проще помочь, если вы предоставите минимальный воспроизводимый пример. См. также здесь. Ваше здоровье.   -  person Henrik    schedule 29.11.2013
comment
не могли бы вы предоставить более простой (минимальный) пример?   -  person Beasterfield    schedule 29.11.2013
comment
Я подозреваю, что ответ может быть хорошо, я бы не начал отсюда... ;)   -  person Stephen Henderson    schedule 29.11.2013
comment
@Besterfield ... извините, что вам нужно спросить .. мне лучше знать .. я приведу лучший пример, но не сегодня, так как меня больше нет дома   -  person Schirnhaden    schedule 29.11.2013


Ответы (1)


Вы можете определить свои условия в виде выражений и использовать их внутри transform. Идея состоит в том, чтобы как можно больше разложить ваши условия на множители.

COND1 <- expression(!is.na(event.2) & !is.na(event.3) & 
                    !is.na(event.4) & !is.na(event.5) & 
                     !is.na(event.6) & !is.na(event.7))
COND2 <- expression(event.4 == 3 & ((1/12*event.2)+event.3) > fixdate) & 
                                    (event.7 == 1 | event.7 == 2))
COND3 <- expression(event.4 == 1 & ((1/12*event.2)+event.3) > fixdate)
COND4 <- expression(event.4 == 2 & ((1/12*event.2)+event.3) > fixdate)
### you continue here with the rest of conditions....

Затем, используя их в transform, вы можете сделать что-то вроде:

transform(df, date = ifelse(eval(COND1) & eval(COND2),((1/12*event.2)+event.3),NA),
transform(df, date = ifelse(eval(COND1) & (eval(COND3)|eval(COND4)),fixdate,NA))
## Note also that the seond "dit" variable is deduced from "date"
transform(df,dit=date-fixdate)  
person agstudy    schedule 29.11.2013
comment
спасибо .. это уменьшит усилия и код, к сожалению, я не могу проголосовать за ваш пост - person Schirnhaden; 30.11.2013