Dear all I try to persuade if statement in my function to work as I want (but I am not very successful:( My question is why my function with if statement is evaluated correctly in case of atomic variables and incorrectly in case of vector variables. Here is an example: #function with if statement fff <- function(otac,sklon) { test <- (otac * 3.69683+286.6*(1/sklon)-0.03100345*otac*sklon) if(test<65) {otac/sklon * 141.76} else {otac * 3.69683+286.6*(1/sklon)-0.03100345*otac*sklon} }> fff(20,70)[1] 40.50286 # correct> fff(50,70)[1] 80.42371 #correct> fff(seq(20,50,5),70)[1] 40.50286 50.62857 60.75429 70.88000 81.00571 91.13143 101.25714 #wrong ----------------------------------------------------------------------------------------------- It does not work because if statement is obviously evaluated as TRUE in all instances and computes wrongly some items in vector according to the first part of the fff function # see direct computation> seq(20,50,5)/70*141.76[1] 40.50286 50.62857 60.75429 70.88000 81.00571 91.13143 101.25714> seq(20,50,5) * 3.69683+286.6*(1/70)-0.03100345*seq(20,50,5)*70[1] 34.62606 42.25900 49.89194 57.52488 65.15783 72.79077 80.42371 On the other hand ifelse works ****************************** fff <- function(otac,sklon) { test <- (otac * 3.69683+286.6*(1/sklon)-0.03100345*otac*sklon) ifelse(test<65, (otac/sklon * 141.76), (otac * 3.69683+286.6*(1/sklon)- 0.03100345*otac*sklon)) }> fff(seq(20,50,5),70)[1] 40.50286 50.62857 60.75429 70.88000 65.15783 72.79077 80.42371 #correct Can anybody help? Thank you in advance Petr Pikal petr.pikal at precheza.cz p.pik at volny.cz -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-help-request at stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
Dear Petr, The test in if isn't vectorized: When the condition is a vector, the first element controls the result. That's why ifelse exists -- to provide a vectorized conditional. John At 11:46 AM 9/19/2002 +0200, Petr Pikal wrote:>Dear all > >I try to persuade if statement in my function to work as I want (but I am >not very >successful:( > >My question is why my function with if statement is evaluated correctly in >case of >atomic variables and incorrectly in case of vector variables. > >Here is an example: > >#function with if statement > >fff <- function(otac,sklon) >{ >test <- (otac * 3.69683+286.6*(1/sklon)-0.03100345*otac*sklon) >if(test<65) >{otac/sklon * 141.76} >else >{otac * 3.69683+286.6*(1/sklon)-0.03100345*otac*sklon} >} > > > fff(20,70) >[1] 40.50286 ># correct > > > fff(50,70) >[1] 80.42371 >#correct > > > fff(seq(20,50,5),70) >[1] 40.50286 50.62857 60.75429 70.88000 81.00571 91.13143 101.25714 >#wrong >----------------------------------------------------------------------------------------------- >It does not work because if statement is obviously evaluated as TRUE in all >instances and computes wrongly some items in vector according to the first >part >of the fff function > ># see direct computation > > seq(20,50,5)/70*141.76 >[1] 40.50286 50.62857 60.75429 70.88000 81.00571 91.13143 101.25714 > > > seq(20,50,5) * 3.69683+286.6*(1/70)-0.03100345*seq(20,50,5)*70 >[1] 34.62606 42.25900 49.89194 57.52488 65.15783 72.79077 80.42371 > >On the other hand ifelse works >****************************** >fff <- function(otac,sklon) >{ >test <- (otac * 3.69683+286.6*(1/sklon)-0.03100345*otac*sklon) >ifelse(test<65, (otac/sklon * 141.76), (otac * 3.69683+286.6*(1/sklon)- >0.03100345*otac*sklon)) >} > > > fff(seq(20,50,5),70) >[1] 40.50286 50.62857 60.75429 70.88000 65.15783 72.79077 80.42371 >#correct > >Can anybody help?----------------------------------------------------- John Fox Department of Sociology McMaster University Hamilton, Ontario, Canada L8S 4M4 email: jfox at mcmaster.ca phone: 905-525-9140x23604 web: www.socsci.mcmaster.ca/jfox ----------------------------------------------------- -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-help-request at stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
You need the vectorized version of if() ... else..., which is ifelse(). Try: fff <- function(otac,sklon) { test <- (otac * 3.69683+286.6*(1/sklon)-0.03100345*otac*sklon) ifelse(test<65, otac/sklon * 141.76, otac * 3.69683+286.6*(1/sklon)-0.03100345*otac*sklon) } which gives:> fff(seq(20,50,5),70)[1] 40.50286 50.62857 60.75429 70.88000 65.15783 72.79077 80.42371 Andy> From: Petr Pikal [mailto:petr.pikal at precheza.cz] > > Dear all > > I try to persuade if statement in my function to work as I > want (but I am not very > successful:( > > My question is why my function with if statement is evaluated > correctly in case of > atomic variables and incorrectly in case of vector variables. > > Here is an example: > > #function with if statement > > fff <- function(otac,sklon) > { > test <- (otac * 3.69683+286.6*(1/sklon)-0.03100345*otac*sklon) > if(test<65) > {otac/sklon * 141.76} > else > {otac * 3.69683+286.6*(1/sklon)-0.03100345*otac*sklon} > } > > > fff(20,70) > [1] 40.50286 > # correct > > > fff(50,70) > [1] 80.42371 > #correct > > > fff(seq(20,50,5),70) > [1] 40.50286 50.62857 60.75429 70.88000 81.00571 > 91.13143 101.25714 > #wrong > -------------------------------------------------------------- > --------------------------------- > It does not work because if statement is obviously evaluated > as TRUE in all > instances and computes wrongly some items in vector according > to the first part > of the fff function > > # see direct computation > > seq(20,50,5)/70*141.76 > [1] 40.50286 50.62857 60.75429 70.88000 81.00571 > 91.13143 101.25714 > > > seq(20,50,5) * 3.69683+286.6*(1/70)-0.03100345*seq(20,50,5)*70 > [1] 34.62606 42.25900 49.89194 57.52488 65.15783 72.79077 80.42371 > > On the other hand ifelse works > ****************************** > fff <- function(otac,sklon) > { > test <- (otac * 3.69683+286.6*(1/sklon)-0.03100345*otac*sklon) > ifelse(test<65, (otac/sklon * 141.76), (otac * > 3.69683+286.6*(1/sklon)- > 0.03100345*otac*sklon)) > } > > > fff(seq(20,50,5),70) > [1] 40.50286 50.62857 60.75429 70.88000 65.15783 72.79077 80.42371 > #correct > > Can anybody help? > > Thank you in advance > Petr Pikal > petr.pikal at precheza.cz > p.pik at volny.cz > > > -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. > -.-.-.-.-.-.-.-.- > r-help mailing list -- Read > http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html > Send "info", "help", or "[un]subscribe" > (in the "body", not the subject !) To: > r-help-request at stat.math.ethz.ch > _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._. > _._._._._._._._._ >------------------------------------------------------------------------------ Notice: This e-mail message, together with any attachments, contains information of Merck & Co., Inc. (Whitehouse Station, New Jersey, USA) that may be confidential, proprietary copyrighted and/or legally privileged, and is intended solely for the use of the individual or entity named in this message. If you are not the intended recipient, and have received this message in error, please immediately return this by e-mail and then delete it. ============================================================================= -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-help-request at stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
Petr Pikal wrote:> > Dear all > > I try to persuade if statement in my function to work as I want (but I am not very > successful:( > > My question is why my function with if statement is evaluated correctly in case of > atomic variables and incorrectly in case of vector variables. > > Here is an example: > > #function with if statement > > fff <- function(otac,sklon) > { > test <- (otac * 3.69683+286.6*(1/sklon)-0.03100345*otac*sklon) > if(test<65) > {otac/sklon * 141.76} > else > {otac * 3.69683+286.6*(1/sklon)-0.03100345*otac*sklon} > } > > > fff(20,70) > [1] 40.50286 > # correct > > > fff(50,70) > [1] 80.42371 > #correct > > > fff(seq(20,50,5),70) > [1] 40.50286 50.62857 60.75429 70.88000 81.00571 91.13143 101.25714 > #wrong > ----------------------------------------------------------------------------------------------- > It does not work because if statement is obviously evaluated as TRUE in all > instances and computes wrongly some items in vector according to the first part > of the fff function > > # see direct computation > > seq(20,50,5)/70*141.76 > [1] 40.50286 50.62857 60.75429 70.88000 81.00571 91.13143 101.25714 > > > seq(20,50,5) * 3.69683+286.6*(1/70)-0.03100345*seq(20,50,5)*70 > [1] 34.62606 42.25900 49.89194 57.52488 65.15783 72.79077 80.42371 > > On the other hand ifelse works > ****************************** > fff <- function(otac,sklon) > { > test <- (otac * 3.69683+286.6*(1/sklon)-0.03100345*otac*sklon) > ifelse(test<65, (otac/sklon * 141.76), (otac * 3.69683+286.6*(1/sklon)- > 0.03100345*otac*sklon)) > } > > > fff(seq(20,50,5),70) > [1] 40.50286 50.62857 60.75429 70.88000 65.15783 72.79077 80.42371 > #correct > > Can anybody help?For the if(){} else{} behaviour see the manual "R Language Definition", section 3.2.1: if(stat1){stat2} else{stat3} is expected to use only eval(stat1)[1] to decide whether stat2 or stat3 should be evaluated next, while ifelse() is expected to work vectorized. Uwe Ligges -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-help-request at stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
Petr Pikal
2002-Sep-19 12:57 UTC
[R] SUMMARY how to use if statement in function correctly
Thanks to all for prompt responses (all of them same or similar). The difference is between vectorised ifelse() form and non vectorised if() form of statement. Therefore the problem was on my improper usage if instead of ifelse. Thanks again Petr Pikal petr.pikal at precheza.cz p.pik at volny.cz -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-help-request at stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
if is not vectorized, it is for control flow in functions. Called with a vector of truth values , it only chooses "if" part or "else" part according to first value in vectos:> x <- -1:1 > x[1] -1 0 1> if (x < 0) "A" else "B"[1] "A" For vectorized computations, you need ifelse, as you have found out. I be,.leave all this is in the help pages. Kjetil Halvorsen Petr Pikal wrote:> > Dear all > > I try to persuade if statement in my function to work as I want (but I am not very > successful:( > > My question is why my function with if statement is evaluated correctly in case of > atomic variables and incorrectly in case of vector variables. > > Here is an example: > > #function with if statement > > fff <- function(otac,sklon) > { > test <- (otac * 3.69683+286.6*(1/sklon)-0.03100345*otac*sklon) > if(test<65) > {otac/sklon * 141.76} > else > {otac * 3.69683+286.6*(1/sklon)-0.03100345*otac*sklon} > } > > > fff(20,70) > [1] 40.50286 > # correct > > > fff(50,70) > [1] 80.42371 > #correct > > > fff(seq(20,50,5),70) > [1] 40.50286 50.62857 60.75429 70.88000 81.00571 91.13143 101.25714 > #wrong > ----------------------------------------------------------------------------------------------- > It does not work because if statement is obviously evaluated as TRUE in all > instances and computes wrongly some items in vector according to the first part > of the fff function > > # see direct computation > > seq(20,50,5)/70*141.76 > [1] 40.50286 50.62857 60.75429 70.88000 81.00571 91.13143 101.25714 > > > seq(20,50,5) * 3.69683+286.6*(1/70)-0.03100345*seq(20,50,5)*70 > [1] 34.62606 42.25900 49.89194 57.52488 65.15783 72.79077 80.42371 > > On the other hand ifelse works > ****************************** > fff <- function(otac,sklon) > { > test <- (otac * 3.69683+286.6*(1/sklon)-0.03100345*otac*sklon) > ifelse(test<65, (otac/sklon * 141.76), (otac * 3.69683+286.6*(1/sklon)- > 0.03100345*otac*sklon)) > } > > > fff(seq(20,50,5),70) > [1] 40.50286 50.62857 60.75429 70.88000 65.15783 72.79077 80.42371 > #correct > > Can anybody help? > > Thank you in advance > Petr Pikal > petr.pikal at precheza.cz > p.pik at volny.cz > > -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- > r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html > Send "info", "help", or "[un]subscribe" > (in the "body", not the subject !) To: r-help-request at stat.math.ethz.ch > _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-help-request at stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
Seemingly Similar Threads
- nice way to find or not a value (problem with numeric(0))
- an unsophisticated question about recoding in a data frame with control structure if {}
- a loop....
- [PATCH] one-time ssh-agent confirmation password
- [Bug 1393] New: patch modifies gnome-ssh-askpass to optionally use one-time password