ALAN SMITH
2008-Jun-04 01:47 UTC
[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
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 #### ## 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 ################################################################################ #### 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) ################# Thank you, Alan P.S. why does ?function not work
This is an FAQ (although it doesn't seem to be listed in the official FAQs. The ``if'' command compares scalars (only, in effect). See ?"if" You need to use the ifelse() function: folds <- function(x,y) ifelse(x-y>=0,2^(x-y),-2^(y-x)) This if for illustrative purposes only. The foregoing would be better done as: folds <- function(x,y) sign(x-y)*2^abs(x-y) cheers, Rolf Turner On 4/06/2008, at 1:47 PM, 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 #### > > ## 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 > ###################################################################### > ########## > #### 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) > ################# > > Thank you, > Alan > > P.S. why does ?function not work > > ______________________________________________ > 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.###################################################################### Attention:\ This e-mail message is privileged and confid...{{dropped:9}}
Simon Blomberg
2008-Jun-04 02:07 UTC
[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
Use ifelse() rather than if () {} else {}. It's vectorized and very useful for applying to elements along vectors. The latter idiom is much better for control of flow in programs and functions. folds <- function (x, y) ifelse(x-y >= 0, 2^(x-y), -(2^abs(x-y))) z <- folds(x, y)> z[1] 16 1 4 4 -4 4 -256>?function works for me. Here's my setup: R version 2.7.0 (2008-04-22) x86_64-pc-linux-gnu Cheers, Simon. On Tue, 2008-06-03 at 20:47 -0500, 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 #### > > ## 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 > ################################################################################ > #### 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) > ################# > > Thank you, > Alan > > P.S. why does ?function not work > > ______________________________________________ > 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.-- Simon Blomberg, BSc (Hons), PhD, MAppStat. Lecturer and Consultant Statistician Faculty of Biological and Chemical Sciences The University of Queensland St. Lucia Queensland 4072 Australia Room 320 Goddard Building (8) T: +61 7 3365 2506 http://www.uq.edu.au/~uqsblomb email: S.Blomberg1_at_uq.edu.au Policies: 1. I will NOT analyse your data for you. 2. Your deadline is your problem. The combination of some data and an aching desire for an answer does not ensure that a reasonable answer can be extracted from a given body of data. - John Tukey.
Erik Iverson
2008-Jun-04 02:09 UTC
[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
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))) } folds2(x, y) should give you your answer...> > ## 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 usedSame 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 workWhat 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 > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.
Steven McKinney
2008-Jun-04 02:19 UTC
[R] help understanding why #function(x, y) (if((x-y)>=0) {2^(x-y)} else{-(2^abs(x-y))})# doesn't work likeI think it should
Hi Alan,> -----Original Message----- > From: r-help-bounces at r-project.org on behalf of ALAN SMITH > Sent: Tue 6/3/2008 6:47 PM > To: r-help at r-project.org > Subject: [R] help understanding why #function(x,y) (if((x-y)>=0) {2^(x-y)} else{-(2^abs(x-y))})# doesn't work likeI think it should > > 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 ####You probably want to use ifelse() instead of if() folds <- function(x, y) (ifelse( ((x - y) >= 0), 2^(x - y), -(2^abs(x - y)))) x <- c(5,6,4,3,5,3,1) y <- c(1,6,2,1,7,1,9) folds <- function(x, y) (ifelse( ((x - y) >= 0), 2^(x - y), -(2^abs(x - y)))) z <- folds(x, y) check <- cbind(x, y, z) check R> x <- c(5,6,4,3,5,3,1) R> y <- c(1,6,2,1,7,1,9) R> folds <- function(x, y) (ifelse( ((x - y) >= 0), 2^(x - y), -(2^abs(x - y)))) R> z <- folds(x, y) R> check <- cbind(x, y, z) R> check x y z [1,] 5 1 16 [2,] 6 6 1 [3,] 4 2 4 [4,] 3 1 4 [5,] 5 7 -4 [6,] 3 1 4 [7,] 1 9 -256> > ## 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 > usedx1 <- c(5,6,4,3,5,3,1) y1 <- c(11,6,2,1,7,1,9) folds <- function(x, y) {ifelse( ((x - y) >= 0), {2^(x - y)}, {-(2^abs(x - y))} ) } z1<-folds(x1,y1) check2<-cbind(x1,y1,z1) check2 R> x1 <- c(5,6,4,3,5,3,1) R> y1 <- c(11,6,2,1,7,1,9) R> folds <- function(x, y) {ifelse( ((x - y) >= 0), {2^(x - y)}, {-(2^abs(x - y))} ) } R> z1<-folds(x1,y1) R> check2<-cbind(x1,y1,z1) R> check2 x1 y1 z1 [1,] 5 11 -64 [2,] 6 6 1 [3,] 4 2 4 [4,] 3 1 4 [5,] 5 7 -4 [6,] 3 1 4 [7,] 1 9 -256> ################################################################################ > #### 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) > ################# > > Thank you, > Alan > > P.S. why does ?function not workIt does work in my ESS R session buffer, so it depends on your setup. try R> ?"function" ?function might not work as the R parser doesn't think you have finished typing in the expression (function objects are typically terminated by the final '}' brace).> > ______________________________________________ > 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. > >Best Steve McKinney
Gabor Grothendieck
2008-Jun-04 03:12 UTC
[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
Try this: data.frame(x, y, folds = (x == y) + sign(x - y) * 2 ^ abs(x - y)) or replace data.frame with cbind if you prefer a matrix result. On Tue, Jun 3, 2008 at 9:47 PM, ALAN SMITH <alansmith2 at gmail.com> 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 #### > > ## 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 > ################################################################################ > #### 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) > ################# > > Thank you, > Alan > > P.S. why does ?function not work > > ______________________________________________ > 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. >
Seemingly Similar Threads
- How to improve the robustness of "loess"? - example included.
- Distances between two datasets of x and y co-ordinates
- error: Error in if (is.na(f0$objective)) { : argument is of length zero
- Request - adding recycled "lwd" parameter to polygon
- Request - adding recycled "lwd" parameter to polygon