user3614783 user3614783 - 3 months ago 11
R Question

Validating arguments before executing a function

I want to validate that each of the two arguments I'm passing to a function are valid.

To do this, I'm checking to see if the 'State' value I assign to my 'state' variable is in a list of states, 'statelist'. Then I check to see if the 'Measure' value I assign to my 'measure' variable is in my list of measures, 'measurelist'. If the first check fails, an "invalid state" error message should be generated. If the second check fails, an "invalid measure" error message should be produced. If both checks pass, I want the function lowest <- function(state, measure) to run.

This is my dataframe, 'data':

school<-c("NYU", "BYU", "USC", "FIT", "Oswego","UCLA","USF","Columbia")
state<-c("NY","UT","CA","NY","NY","CA", "CA","NY")
measure<-c("MSAT","MSAT","GPA","MSAT","MSAT","GPA","GPA","GPA")
score<-c(590, 490, 2.9, 759, 550, 1.2, 3.1, 3.2)
data<-data.frame(school,state, measure,score)


This function checks that I have a valid state abbreviation:

teststate<-function(state){
statelist<-(c(state.abb,"DC","GU","MP","PR","VI"))
if(state %in% statelist){
testmeasure(measure)
} else{
stop("invalid state")
}
}


This function checks that the measure I'm specifying is in my list of measures:

testmeasure<-function(measure){
measurelist<-c("MSAT","GPA","VSAT")
if(measure %in% measurelist){
lowest(state, measure)
} else{
stop("invalid measure")
}
}


This is the main function that should run after the validity checks are successful:

lowest <- function(state, measure){
answer<-subset(data,subset=(state==State & measure==Measure))
order.answer<-order(answer$score,answer$school)
answer1<-as.matrix(answer[order.answer,])
answer1[1,1]
}


For this example:

lowest("NY","MSAT")


the correct answer should be [1] "Owsego", but when I run the code in its entirety, it never completes, and the console simply shows:

+ lowest("NY","MSAT")
+


When I tested each of these modules independently, outside of a function, they worked.

Answer

Try this:

lowestV2 <- function(State,Measure){
  ##
  if(State %in% c(state.abb,"DC","GU","MP","PR","VI")){
    if(Measure %in% c("MSAT","GPA","VSAT")){
      answer<-subset(data,subset=(state==State & measure==Measure))
      order.answer<-order(answer$score,answer$school)
      answer1<-as.matrix(answer[order.answer,])
      answer1[1,1]
    } else {
      stop("invalid measure")
    }
  } else {
    stop("invalid state")
  }
  ##
}
##
> lowestV2("NY","MSAT")
[1] "Oswego"

Unless you are doing error catching for some type of complex situation / condition, you might as well just include the handling directly in the main function rather than make calls to external error handling functions for each condition.

Comments