简体   繁体   中英

R: recommendation on how to compute new columns on multiple condition of others for every row in data.frame

For every entry in rows i need to compute two variables as new columns in a data.frame depending conditional on more than 60 other columns. I would like your recommendation on how to realize that elegant (while and for, with, ifelse, foreach, by or ddply?). I don't like to do that manually like i did for the first cases in the example code and i don't care for performance.

Further: Probably i would not need to ask if i would have understood how to use functions like transform (with ddply or by) and what they do. Thus i hope you can recommend good tutorials on that, maybe relating to my case. I found a lot but in different context and was not able to comprehend it entrily or transcribe it for my case.

My case: I have three columns for each of 20 events representing the kind and date of that event. For each row I need to compute (and save to that data.frame) the difference in time between one special event (depending on whether a special kind happened before or after another) and a date fixed for every entry in rows. Furthermore i need to save the date of that event.

This is how i did (it works, but it is running only through the first cases):

#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)

You can define your conditions as expressions and use them within transform . The idea is to factorize your conditions at most as possible .

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....

Then using them within transform you can do something like:

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)  

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM