如何在不使用嵌套if else语句的情况下处理多个参数?

时间:2017-05-08 16:49:03

标签: r function if-statement

我正在尝试编写一个最多有6个潜在条件的函数。该函数创建一个线性模型,该模型最多可包含三个参数,并且可以缩放或不缩放。我尝试使用嵌套的if else语句,但遇到了问题,因为我有太多的条件(缩放或不是X 3ivs可能= 6个潜在条件)。如何简化代码以便于阅读?

这是我尝试编写的内容,但它目前无法正常工作。

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)

这是我遇到的错误,但我正在尝试简化代码,而不仅仅是解决错误:

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

2 个答案:

答案 0 :(得分:0)

这是你的功能组织。我希望它有效,因为我并不关心函数的功能,只是为了ifelse(test, yes, no)

的参数
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(test = scale,
         yes = ifelse(test = !is.na(iv3),
                      yes = {
                        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))
                      },
                      no = ifelse(test = !is.na(iv2),

                                  yes = {
                                    x<-lm(scale(dv)~scale(iv1)+scale(iv2))
                                    names(x$coefficients)<-c(dn,in1,in2)
                                    return(summary(x))
                                  },

                                  no = {
                                    x<-lm(scale(dv)~scale(iv1))
                                    names(x$coefficients)<-c(dn,in1)
                                    return(summary(x))
                                  })),
         no =  ifelse(test = !is.na(iv3),
                          yes = return(summary(lm((dv)~(iv1)+(iv2)+(iv3)))),

                          no = ifelse(test = !is.na(iv2),
                                      yes = return(summary(lm((dv)~(iv1)+(iv2)))),
                                      no = return(summary(lm((dv)~(iv1))))))

         ) #format=ifelse(cond,if_true,if_false)


}

答案 1 :(得分:0)

也许您应该从函数参数构建一个公式,然后将其传递给lm

,而不是使用一堆library(tidyverse) lm2 <- function(dep_var, ind_var, ..., data, scaled = FALSE) { if (scaled) { data <- mutate_if(data, is.numeric, scale) } form <- paste(dep_var, '~', paste(ind_var, ..., sep = '+')) %>% as.formula() lm(form, data = data) %>% summary() } # tests # 1 independent var lm(Petal.Width ~ Sepal.Width, data = iris) %>% summary() lm2('Petal.Width', 'Sepal.Width', data = iris) # 2 independent var lm(Petal.Width ~ Sepal.Width + Sepal.Length, data = iris) %>% summary() lm2('Petal.Width', 'Sepal.Width', 'Sepal.Length', data = iris) # test scale option iris_scaled <- mutate(iris, Petal.Width = scale(Petal.Width), Sepal.Width = scale(Sepal.Width)) lm(Petal.Width ~ Sepal.Width, data = iris_scaled) %>% summary() lm2('Petal.Width', 'Sepal.Width', data = iris, scaled = TRUE) 语句。
# Tested on docker with python 2
# docker run --rm -it python:2 bash

pip install django_filter==0.11.0
pip install django_filter==0.15.3
find / -name django_filters -type d
# Prints
# /usr/local/lib/python2.7/site-packages/django_filters
pip uninstall django_filter

easy_install django_filter==0.11.0
easy_install django_filter==0.15.3
find / -name django_filters -type d
# Prints
# /usr/local/lib/python2.7/site-packages/django_filter-0.11.0-py2.7.egg/django_filters
# /usr/local/lib/python2.7/site-packages/django_filter-0.15.3-py2.7.egg/django_filters
pip uninstall django_filter
pip uninstall django_filter