[R] Need help figuring out sapply (and similar functions) with multiple parameter user defined function

William Dunlap wdunlap at tibco.com
Fri Dec 6 17:43:31 CET 2013


> I have been researching and it appears that I should be using the sapply
> function to apply the evaluate.question function above to each row in
> the data frame like this

Read the documentation more closely: sapply(dataFrame, func)
applies func() to each column, not row, of dataFrame.

> preferences <- sapply(df, evaluate.questions, function(x,y,z)
> evaluate.questions(df['Q1'],df['Q2'],df['Q3']))

Furthermore,
    sapply(X = dataFrame, FUN = func, extraArgument)
calls
    func(dataFrame[, i], extraArgument)
for i in seq_len(ncol(dataFrame).

One problem is that FUN=evaluate.questions takes 3 arguments and
you give it only 2.  Another problem is that the third argument you
pass to sapply is a function (of 3 arguments) and FUN is not expecting
any of its arguments to be functions.

It may be easier for you to not use sapply here, but to use for-loops and
come up with something that works.  (Write tests that will indicate whether
it works or not in a variety of situations.)  Then transform it to use things
like ifelse() and sapply() to make it more readable and run faster.

> Unfortunately this doesn't work and the problem appears that the sapply
> function is not feeding the parameters to the evaluate.questions
> function as I expect.  Can someone provide some guidance on what I am
> doing wrong?

Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com


> -----Original Message-----
> From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf
> Of Walter Anderson
> Sent: Friday, December 06, 2013 7:44 AM
> To: r-help at r-project.org
> Subject: [R] Need help figuring out sapply (and similar functions) with multiple parameter
> user defined function
> 
> I am having trouble understanding how to use sapply (or similar
> functions) with a user defined function with multiple parameters.
> 
> I have the following functions defined
> 
>     q1.ans <- function(x)
>     {
>        retVal = 0
>        if (x == 1) {
>          retVal = 1
>        } else if (x ==2) {
>          retVal = 2
>        }
>        return (retVal)
>     }
>     q2.ans <- function(x)
>     {
>        retVal = 0
>        if (x == 1) {
>          retVal = 1
>        } else if (x ==2) {
>          retVal = 3
>        }
>        return (retVal)
>     }
>     q3.ans <- function(x)
>     {
>        retVal = 0
>        if (x == 1) {
>          retVal = 2
>        } else if (x ==2) {
>          retVal = 3
>        }
>        return (retVal)
>     }
> 
>     evaluate.questions <- function(q.1,q.2,q.3)
>     {
>        a <- q1.ans(q.1)
>        b <- q2.ans(q.2)
>        c <- q3.ans(q.3)
>        retVal = 0   # Set default value to be no preference
>        # The following code only implements those values from the state
>        # machine that show a preference (ID's 5,9,11,13-15,17-18,21,23-27)
>        if (a == 0) {
>          if (b == 1) {
>            if (c == 1) {
>              retVal = 1  # State machine ID 5
>            }
>          } else if (b == 2) {
>            if (c == 2) {
>              retVal = 2  # State machine ID 9
>            }
>          }
>        } else if (a == 1) {
>          if (b == 0) {
>            if (c == 1) {
>              retVal = 1  # State machine ID 11
>            }
>          } else if (b == 1) {
>            retVal = 1    # State machine ID's 13-15, value of C doesn't matter
>          } else if (b == 2) {
>            if (c == 1) {
>              retVal = 1  # State machine ID 17
>            } else if (c == 2) {
>              retVal = 2  # State machine ID 18
>            }
>          }
>        } else if (a == 2) {
>          if (b == 0) {
>            if (c == 2) {
>              retVal = 2  # State machine ID 21
>            }
>          } else if (b == 1) {
>            if (c == 1) {
>              retVal = 1  # State machine ID 23
>            } else if (c == 2) {
>              retVal = 2  # State machine ID 24
>            }
>          } else if (b == 2) {
>            retVal = 2    # State machine ID's 25-27, value of C doesn't matter
>          }
>        }
>        return (retVal)
>     }
> 
> And a data set that looks like this:
> 
>     ID,Q1,Q2,Q3
>     1,2,2,2
>     2,2,1,1
>     3,1,1,1
>     4,1,2,2
>     5,2,2,1
>     6,1,2,1
>     ...
> 
> 
> I have been researching and it appears that I should be using the sapply
> function to apply the evaluate.question function above to each row in
> the data frame like this
> 
> preferences <- sapply(df, evaluate.questions, function(x,y,z)
> evaluate.questions(df['Q1'],df['Q2'],df['Q3']))
> 
> Unfortunately this doesn't work and the problem appears that the sapply
> function is not feeding the parameters to the evaluate.questions
> function as I expect.  Can someone provide some guidance on what I am
> doing wrong?
> 
> This is the error message I am getting:
> 
> Error in x --1 :
>    Comparison (1) is possible only for atomic and list types
> In addition: warning messages:
> In if (x == 1) { :
>    the condition has length > 1 and only the first element will be used
> 
> 	[[alternative HTML version deleted]]
> 
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.



More information about the R-help mailing list