# Re: [R] help understanding why #function(x, y) (if((x-y)>=0) {2^(x-y)} else{-(2^abs(x-y))})# doesn't work like I think it should

From: Erik Iverson <iverson_at_biostat.wisc.edu>
Date: Tue, 03 Jun 2008 21:09:23 -0500

Alan -

ALAN SMITH wrote:
> Hello R users and developers,
> I am trying to write several functions (fairly new at this) in order
> to avoid using loops on large data frames (because they are slow). I
> wrote the function below and it seems to get hung on the first part of
> the if statement and then applies that condition to rest of the
> function. So if (x-y) is greater than 0 the function uses the true
> statement for the calculations. Could someone please offer some
> advise on how to write these functions a little better or a type
> "apply" that I may use with two (or more) different vectors of data
> required by a single functions.
> ####################### Examples
> #######################################################
> ## example 1 ###
> x<-c(5,6,4,3,5,3,1)
> y<-c(1,6,2,1,7,1,9)
> folds<-function(x,y) (if((x-y)>=0) {2^(x-y)} else{-(2^abs(x-y))})
> z<-folds(x,y)
> check<-cbind(x,y,z)
> View(check)
>
> Warning message:
> In if ((x - y) >= 0) { :
> the condition has length > 1 and only the first element will be used
> ### why will it only use the first element and how to I get around
> this ####

When learning R, you have the power of the interpreter at all times. You have defined x and y above to be numeric vectors of length 7 each. Try typign x - y at the interpreter, and you'll see you get another numeric vector of length 7. Now try (x - y) >= 0 , and you'll get a logical vector of length 7. However, if does not want a logical vector of length 7, it wants a logical vector of length 1, see the 'cond' argument of ?if. However, the ifelse function should do what you want, see ?ifelse.

Here's an example using it

folds2 <- function(x, y) {

ifelse(x - y >= 0, 2^(x - y), -(2^abs(x - y))) }

>
> ## example 2 making the fist comparison negative ###
> x1<-c(5,6,4,3,5,3,1)
> y1<-c(11,6,2,1,7,1,9)
> folds<-function(x,y) (if((x-y)>=0) {2^(x-y)} else{-(2^abs(x-y))})
> z1<-folds(x1,y1)
> check2<-cbind(x1,y1,z1)
> View(check2)
> Warning message:
> In if ((x - y) >= 0) { :
> the condition has length > 1 and only the first element will be used

Same idea as above here...

> ################################################################################
> #### loop I am trying to avoid writing many many times #####
> folds2<-NULL
> xy<-as.data.frame(cbind(x,y))
> for (i in 1:nrow(xy)) {
> diff<-xy\$x[i]-xy\$y[i]
> folds2[i]<-if(diff>=0) {2^diff} else{-(2^abs(diff))}
> }
> xyz<-cbind(xy,folds2)
> View(xyz)
> #################

I'm not exactly sure what you'd like here, but hopefully with the above you can figure it out. Let me know if you have any questions!

Best,
Erik Iverson

>
> Thank you,
> Alan
>
> P.S. why does ?function not work

What do you expect it to do? It shows the help page for 'function' here.

>
> ______________________________________________
> R-help_at_r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help