lundi 8 mai 2017

How can I handle multiple parameters without using nested if else statements?

I am trying to write a function that has up to 6 potential conditions. The function creates a linear model that could have up to three parameters and is either scaled or not scaled. I tried using nested if else statements, but have run into issues because I have too many conditions (scaled or not X 3ivs possible = 6 potential conditions). How can I simplify my code so it is easier to read?

This is what I tried to write, but it does not currently work.

test<-data.frame(a=sample.int(20,10,replace=T),b=sample.int(20,10,replace=T),c=sample.int(20,10,replace=T),d=sample.int(20,10,replace=T))

lm3iv<-function(dv,iv1,iv2=NA,iv3=NA,df,scale=F){
  dn<-dv;in1<-iv1;in2<-iv2;in3<-iv3 #stores the names of variables/elements specified in function
  dv<-eval(parse(text=paste0(df,"$",dv))) #Store output of (df,"$",dv) as variable dv; parse=trun string into text; eval=return the values given by an expression that is passed to eval (by parse in this case).
  #return(dv)
  iv1<-eval(parse(text=paste0(df,"$",iv1)))
  if(!is.na(iv2)){iv2<-eval(parse(text=paste0(df,"$",iv2)))}
  if(!is.na(iv3)){iv3<-eval(parse(text=paste0(df,"$",iv3)))}
  ifelse(scale,
         ifelse(!is.na(iv3),
                {
                  x<-lm(scale(dv)~scale(iv1)+scale(iv2)+scale(iv3))
                  names(x$coefficients)<-c(dn,in1,in2,in3) #set names of coefficients (element of x) from x (object defined in above line); names=pulling specific elements of coefficients
                  return(summary(x))
                },
                ifelse(!is.na(iv2),{
                  x<-lm(scale(dv)~scale(iv1)+scale(iv2))
                  names(x$coefficients)<-c(dn,in1,in2)
                  return(summary(x))
                },
                {
                  x<-lm(scale(dv)~scale(iv1))
                  names(x$coefficients)<-c(dn,in1)
                  return(summary(x))
                },
                ifelse(!is.na(iv3),
                       return(summary(lm((dv)~(iv1)+(iv2)+(iv3)))),
                       ifelse(!is.na(iv2),
                              return(summary(lm((dv)~(iv1)+(iv2)))),
                              return(summary(lm((dv)~(iv1)))))))
         ) #format=ifelse(cond,if_true,if_false)
  )

}

#tried adding list() before the first summary to return model outpot and the model its self; have to add the model again after the comma after summary() - e.g., lm(scale(dv)~scale(iv1)+scale(iv2)+scale(iv3))) (same model being summarized). Have to create a variable when passing the data into the model. When reading output -> model.output(model.std.el.ns.tw[[1]],model.std.el.ns.tw[[2]]).

lm3iv("a","b","c","d",df="test",scale=F)

This is the error I'm getting, but I am trying to simplify my code, not just solve the error:

Error in ifelse(scale, ifelse(!is.na(iv3), { :
argument "no" is missing, with no default

Aucun commentaire:

Enregistrer un commentaire