Search code examples
rfunctionany

How do you use any, if_any, or something analogous in a user defined function in R?


I am applying a function to a dataframe. I want to apply a certain function if any of the group of parameters are not NA. That is, if any of these: P1TN, P1TP, P1TSS, P2TN, P3TN, P3TP, P3TSS are not NA, then run the first statement in the second and third ifelse statements. Normally, for this operation I would use any or if_any, but I can't figure out how to do this in a function.

The best I can come up with is !is.na(P1TN) & !is.na(P2TN) & !is.na(P3TN) & !is.na(P1TP) & !is.na(P3TP) & !is.na(P1TSS) & !is.na(P3TSS) which isn't great...

I can change the data prior to the function, but ideally I would like to do it inside:

df$P <- apply(df[,c("P1TN","P1TP","P1TSS","P2TN","P3TN","P3TP","P3TSS")], 1, 
              function(r) ifelse(all(is.na(r)),"No", "Yes"))

Example Data:

df <-data.frame(L=c(100,200,800,1600), P=c("Yes", "No", "Yes", NA),
                P1TN=c(220,NA,640,99), P1TP=c(160,NA,120,33), P1TSS=c(1200,NA,1600,205), 
                P2TN=c(220,NA,640,NA), 
                P3TN=c(NA,NA,640,NA),  P3TP=c(360,NA,640,NA), P3TSS=c(NA,NA,640,NA),
                Ph=c("As-Built","Design","Design","Complete"),
                BD=c("2018-01-20",NA,NA,"2020-08-16"))

Function:

IA <- function(L, P ,P1TN, P1TP, P1TSS, P2TN, P3TN, P3TP, P3TSS, Ph, BD){
  ifelse(is.na(BD) & Ph %in% c("Design","Construction Document","Schematic Design","Design Development","Concept") | BD >= as.POSIXct("2020-07-01 00:00:00"),
    ifelse(P=="Yes" | is.na(P) & !is.na(P1TN) & !is.na(P2TN) & !is.na(P3TN) & !is.na(P1TP) & !is.na(P3TP) & !is.na(P1TSS) & !is.na(P3TSS),
      ((sum(P1TN,P2TN,P3TN,na.rm=T)/18.08) + (sum(P1TP,P3TP,na.rm=T)/2.23) + (sum(P1TSS,P3TSS,na.rm=T)/8046))/3, L*0.02),
    ifelse(P=="Yes" | is.na(P) & !is.na(P1TN) & !is.na(P2TN) & !is.na(P3TN) & !is.na(P1TP) & !is.na(P3TP) & !is.na(P1TSS) & !is.na(P3TSS),
      ((sum(P1TN,P2TN,P3TN,na.rm=T)/7.69) + (sum(P1TP,P3TP,na.rm=T)/1.91) + ((sum(P1TSS,P3TSS,na.rm=T)/0.43)/2000))/3, L*0.02))
} 

Format dates and run function:

df$BD <- as.POSIXct(df$BD)
df$IA <- IA(df$L, df$P, df$P1TN, df$P1TP, df$P1TSS, df$P2TN, df$P3TN, df$P3TP, df$P3TSS, df$Ph, df$BD)
df

Solution

  • You can replace

    !is.na(P1TN) & !is.na(P2TN) & !is.na(P3TN) & !is.na(P1TP) & !is.na(P3TP) & !is.na(P1TSS) & !is.na(P3TSS) 
    

    by

    complete.cases(df[,3-9])
    

    Regards,