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

Walter Anderson wandrson01 at gmail.com
Fri Dec 6 20:54:24 CET 2013


Thanks again!

Can the ifelse statement be nested like

ifelse(condition1,
     ifelse(condition2,yes,no)
     ifelse(condition3,yes,no)
)

?
On 12/06/2013 12:23 PM, William Dunlap wrote:
>> I understand that such for loops aren't 'best practice' in R and am
>> trying to learn its approach.
> sapply() is an encapsulated loop and loops have their place in R.
> 'Best practice' is a nebulous term, but explicit loops can make
> code that is hard to understand (by a compiler or by a human)
> and any loop at the R-code level will generally make code run
> more slowly.  However, depending on your background, explicit
> loops may be easier for you to write and understand, so you
> may get an answer faster by using loops.
>
>>> Then transform it to use things
>>> like ifelse() and sapply() to make it more readable and run faster.
> Changing your 'if' statements to calls to the vectorized 'ifelse' will
> probably make looping unneeded.  E.g., your q1.ans() only works
> on a scalar, forcing you to use sapply (or the superior vapply) to
> work on vectors:
>
>      q1.ans <- function(x)
>      {
>         retVal = 0
>         if (x == 1) {
>           retVal = 1
>         } else if (x ==2) {
>           retVal = 2
>         }
>         return (retVal)
>      }
> as in
>      > q1.ans(1:3)
>     [1] 1
>     Warning message:
>     In if (x == 1) { :
>       the condition has length > 1 and only the first element will be used
>     > sapply(1:3, q1.ans)
>     [1] 1 2 0
>
> You can change it to work on a vector by using ifelse:
>     q1a.ans <- function(x) {
>        ifelse(x==1,
>                   1,  # return 1's where x had 1's
>                   ifelse(x==2,
>                             2, # return 2's where x had 2's
>                             0)) # return 0 where x had something else
>      }
> used as
>      > q1a.ans(1:3)
>     [1] 1 2 0
>
> Bill Dunlap
> Spotfire, TIBCO Software
> wdunlap tibco.com
>
>
>> -----Original Message-----
>> From: Walter Anderson [mailto:wandrson01 at gmail.com]
>> Sent: Friday, December 06, 2013 9:58 AM
>> To: William Dunlap; r-help at r-project.org
>> Subject: Re: [R] Need help figuring out sapply (and similar functions) with multiple
>> parameter user defined function
>>
>> On 12/06/2013 10:43 AM, William Dunlap wrote:
>>>> 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.
>> I misunderstood.  I thought it was apply the func to each row...  My mistake
>>>> 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.
>> I will need to think about this, I am not sure I understand.  I really
>> don't seem to understand how any of the apply functions seem to work.
>>> 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.
>> I already have tested my functions by using a for loop, and they work.
>> Here is the for loop I use.
>>
>> for (indx in 1:length(df$ID)) {
>>       df$Preference <-
>> evaluate.questions(df$Q1[indx],df$Q2[indx],df$Q3[indx])
>> }
>>
>> I understand that such for loops aren't 'best practice' in R and am
>> trying to learn its approach.  Thank you for the suggestions!
>>>> 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
>>>
>>>
>



More information about the R-help mailing list