Thanks. This worked!! :) Fisher <- ifelse(!("Fisher" %in% names(obj$spec)), FALSE, obj$spec$Fisher) Steven At 08:43 AM 12/14/2014, Ben Tupper wrote:>Hi, > >Does this work for you? It simply tests if the name Fisher is found >among the names of the elements of spec. > >obj = list(spec = list) >Fisher <- ifelse(!("Fisher" %in% names(obj$spec)), FALSE, obj$spec$Fisher) > >Cheers, >Ben > >On Dec 14, 2014, at 8:07 AM, Steven Yen <syen04 at gmail.com> wrote: > > > My obj does not always come with a logical variable defined. So I do > > > > my.foo <- function(obj,df,digits=5){ > > if (!is.na("obj$spec$Fisher")) Fisher<-obj$spec$Fisher > > ... > > } > > > > This works when "Fisher" is defined in/passed from obj. When it > is not, I get error: > > > > Error in (!is.na("obj$spec$Fisher")) & Fisher : > > operations are possible only for numeric, logical or complex types > > > > I tried exist(Fisher), missing(Fisher)... to no vail. Any idea? Thanks. > > > > ______________________________________________ > > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > > 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. > >Ben Tupper >Bigelow Laboratory for Ocean Sciences >60 Bigelow Drive, P.O. Box 380 >East Boothbay, Maine 04544 >http://www.bigelow.org
Martin Maechler
2014-Dec-23 09:05 UTC
[R] Do NOT use ifelse() if you can use if(.) else . [was "Checking .."]
>>>>> Steven Yen <syen04 at gmail.com> >>>>> on Sun, 14 Dec 2014 09:30:56 -0500 writes: >>>>> Steven Yen <syen04 at gmail.com> >>>>> on Sun, 14 Dec 2014 09:30:56 -0500 writes:> Thanks. This worked!! :) > Fisher <- ifelse(!("Fisher" %in% names(obj$spec)), FALSE, obj$spec$Fisher) "worked", yes. But please --- for the mailing list archives --- do use better code. Unfortunately, ifelse() is used and has been advertized much too often in cases where it is very sub-optimal efficiency wise. ifelse(Cond, A, B) should only be used when the condition 'Cond', a logical vector can be (and typically is) of length > 1 {and even then, it maybe a nice short cut, but often still suboptimal efficiency wise ... but let's not get there} In cases like this one when the condition 'Cond' is a simple TRUE or FALSE (i.e. of length 1), using if(Cond) A else B instead of ifelse(Cond, A, B) is 1. much more R - like [[ "everything you do is a function call" ]] hence much more elegant 2. considerably more efficient. 3. :-) less typing: uses two "," less ;-) > require(microbenchmark) Loading required package: microbenchmark > x <- setNames(,LETTERS) > y <- setNames(letters, runif(letters)) > z <- pi > microbenchmark(r1 <- ifelse(z > 3, x, y), r2 <- if(z > 3) x else y, times=1000) Unit: nanoseconds expr min lq mean median uq max neval cld r1 <- ifelse(z > 3, x, y) 4466 4971.5 5498.928 5244 5673.5 31705 1000 b r2 <- if (z > 3) x else y 171 212.0 265.241 264 291.0 3130 1000 a > i.e., roughly a factor of 20 times more efficient Martin Maechler, ETH Zurich and R Core Team. > At 08:43 AM 12/14/2014, Ben Tupper wrote: >> Hi, >> >> Does this work for you? It simply tests if the name Fisher is found >> among the names of the elements of spec. >> >> obj = list(spec = list) >> Fisher <- ifelse(!("Fisher" %in% names(obj$spec)), FALSE, obj$spec$Fisher) >> >> Cheers, >> Ben >> >> On Dec 14, 2014, at 8:07 AM, Steven Yen <syen04 at gmail.com> wrote: >> >> > My obj does not always come with a logical variable defined. So I do >> > >> > my.foo <- function(obj,df,digits=5){ >> > if (!is.na("obj$spec$Fisher")) Fisher<-obj$spec$Fisher >> > ... >> > } >> > >> > This works when "Fisher" is defined in/passed from obj. When it >> is not, I get error: >> > >> > Error in (!is.na("obj$spec$Fisher")) & Fisher : >> > operations are possible only for numeric, logical or complex types >> > >> > I tried exist(Fisher), missing(Fisher)... to no vail. Any idea? Thanks.
peter dalgaard
2014-Dec-23 11:57 UTC
[R] Do NOT use ifelse() if you can use if(.) else . [was "Checking .."]
> On 23 Dec 2014, at 10:05 , Martin Maechler <maechler at stat.math.ethz.ch> wrote: > > > In cases like this one when the condition 'Cond' is a > simple TRUE or FALSE (i.e. of length 1), using > > if(Cond) A else B > > instead of > > ifelse(Cond, A, B) > > is > > 1. much more R - like [[ "everything you do is a function call" ]] > hence much more elegant > > 2. considerably more efficient. > > 3. :-) less typing: uses two "," less ;-) >4. Considerably less confusing in terms of the class of the result.> ifelse (TRUE, Sys.Date(), as.Date("2014-1-1") )[1] 16427> ifelse (FALSE, Sys.Date(), as.Date("2014-1-1") )[1] 16071> if (TRUE) Sys.Date() else as.Date("2014-1-1")[1] "2014-12-23"> if (FALSE) Sys.Date() else as.Date("2014-1-1")[1] "2014-01-01" (S/R made the Solomonic decision to take the class of the result of ifelse() from the _condition_ part, which is the only possibility common to both cases, but most likely also something that noone would ever actually want.) -- Peter Dalgaard, Professor, Center for Statistics, Copenhagen Business School Solbjerg Plads 3, 2000 Frederiksberg, Denmark Phone: (+45)38153501 Email: pd.mes at cbs.dk Priv: PDalgd at gmail.com
John Fox
2014-Dec-23 14:10 UTC
[R] Do NOT use ifelse() if you can use if(.) else . [was "Checking .."]
Hi, Sorry to chime in late, but here's an alternative solution, without conditionals:> obj <- list(spec=list("Fisher"=TRUE, "Tukey"=FALSE))> obj$spec$Fisher[1] TRUE> !is.null(obj$spec$Fisher) && obj$spec$Fisher[1] TRUE> obj$spec$PearsonNULL> !is.null(obj$spec$Pearson) && obj$spec$Pearson[1] FALSE I hope this helps, John ------------------------------------------------ John Fox, Professor McMaster University Hamilton, Ontario, Canada http://socserv.mcmaster.ca/jfox/ On Tue, 23 Dec 2014 10:05:47 +0100 Martin Maechler <maechler at stat.math.ethz.ch> wrote:> >>>>> Steven Yen <syen04 at gmail.com> > >>>>> on Sun, 14 Dec 2014 09:30:56 -0500 writes: > >>>>> Steven Yen <syen04 at gmail.com> > >>>>> on Sun, 14 Dec 2014 09:30:56 -0500 writes: > > > Thanks. This worked!! :) > > Fisher <- ifelse(!("Fisher" %in% names(obj$spec)), FALSE, obj$spec$Fisher) > > "worked", yes. > > But please --- for the mailing list archives --- > do use better code. > > Unfortunately, ifelse() is used and has been advertized much too > often in cases where it is very sub-optimal efficiency wise. > ifelse(Cond, A, B) should only be used when the condition > 'Cond', a logical vector can be (and typically is) of length > 1 > {and even then, it maybe a nice short cut, but often still suboptimal > efficiency wise ... but let's not get there} > > In cases like this one when the condition 'Cond' is a > simple TRUE or FALSE (i.e. of length 1), using > > if(Cond) A else B > > instead of > > ifelse(Cond, A, B) > > is > > 1. much more R - like [[ "everything you do is a function call" ]] > hence much more elegant > > 2. considerably more efficient. > > 3. :-) less typing: uses two "," less ;-) > > > require(microbenchmark) > Loading required package: microbenchmark > > x <- setNames(,LETTERS) > > y <- setNames(letters, runif(letters)) > > z <- pi > > microbenchmark(r1 <- ifelse(z > 3, x, y), r2 <- if(z > 3) x else y, times=1000) > Unit: nanoseconds > expr min lq mean median uq max neval cld > r1 <- ifelse(z > 3, x, y) 4466 4971.5 5498.928 5244 5673.5 31705 1000 b > r2 <- if (z > 3) x else y 171 212.0 265.241 264 291.0 3130 1000 a > > > > i.e., roughly a factor of 20 times more efficient > > > Martin Maechler, > ETH Zurich and R Core Team. > > > > At 08:43 AM 12/14/2014, Ben Tupper wrote: > >> Hi, > >> > >> Does this work for you? It simply tests if the name Fisher is found > >> among the names of the elements of spec. > >> > >> obj = list(spec = list) > >> Fisher <- ifelse(!("Fisher" %in% names(obj$spec)), FALSE, obj$spec$Fisher) > >> > >> Cheers, > >> Ben > >> > >> On Dec 14, 2014, at 8:07 AM, Steven Yen <syen04 at gmail.com> wrote: > >> > >> > My obj does not always come with a logical variable defined. So I do > >> > > >> > my.foo <- function(obj,df,digits=5){ > >> > if (!is.na("obj$spec$Fisher")) Fisher<-obj$spec$Fisher > >> > ... > >> > } > >> > > >> > This works when "Fisher" is defined in/passed from obj. When it > >> is not, I get error: > >> > > >> > Error in (!is.na("obj$spec$Fisher")) & Fisher : > >> > operations are possible only for numeric, logical or complex types > >> > > >> > I tried exist(Fisher), missing(Fisher)... to no vail. Any idea? Thanks. > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > 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.
Ben Tupper
2014-Dec-23 18:27 UTC
[R] Do NOT use ifelse() if you can use if(.) else . [was "Checking .."]
On Dec 23, 2014, at 4:05 AM, Martin Maechler <maechler at stat.math.ethz.ch> wrote:>>>>>> Steven Yen <syen04 at gmail.com> >>>>>> on Sun, 14 Dec 2014 09:30:56 -0500 writes: >>>>>> Steven Yen <syen04 at gmail.com> >>>>>> on Sun, 14 Dec 2014 09:30:56 -0500 writes: > >> Thanks. This worked!! :) >> Fisher <- ifelse(!("Fisher" %in% names(obj$spec)), FALSE, obj$spec$Fisher) > > "worked", yes. > > But please --- for the mailing list archives --- > do use better code. > > Unfortunately, ifelse() is used and has been advertized much too > often in cases where it is very sub-optimal efficiency wise. > ifelse(Cond, A, B) should only be used when the condition > 'Cond', a logical vector can be (and typically is) of length > 1 > {and even then, it maybe a nice short cut, but often still suboptimal > efficiency wise ... but let's not get there} > > In cases like this one when the condition 'Cond' is a > simple TRUE or FALSE (i.e. of length 1), using > > if(Cond) A else B > > instead of > > ifelse(Cond, A, B) > > is > > 1. much more R - like [[ "everything you do is a function call" ]] > hence much more elegant > > 2. considerably more efficient. > > 3. :-) less typing: uses two "," less ;-) > >> require(microbenchmark) > Loading required package: microbenchmark >> x <- setNames(,LETTERS) >> y <- setNames(letters, runif(letters)) >> z <- pi >> microbenchmark(r1 <- ifelse(z > 3, x, y), r2 <- if(z > 3) x else y, times=1000) > Unit: nanoseconds > expr min lq mean median uq max neval cld > r1 <- ifelse(z > 3, x, y) 4466 4971.5 5498.928 5244 5673.5 31705 1000 b > r2 <- if (z > 3) x else y 171 212.0 265.241 264 291.0 3130 1000 a >> > > i.e., roughly a factor of 20 times more efficient >Wow! This is great, and I had no idea I was misusing ifelse. Thanks! Ben> > Martin Maechler, > ETH Zurich and R Core Team. > > >> At 08:43 AM 12/14/2014, Ben Tupper wrote: >>> Hi, >>> >>> Does this work for you? It simply tests if the name Fisher is found >>> among the names of the elements of spec. >>> >>> obj = list(spec = list) >>> Fisher <- ifelse(!("Fisher" %in% names(obj$spec)), FALSE, obj$spec$Fisher) >>> >>> Cheers, >>> Ben >>> >>> On Dec 14, 2014, at 8:07 AM, Steven Yen <syen04 at gmail.com> wrote: >>> >>>> My obj does not always come with a logical variable defined. So I do >>>> >>>> my.foo <- function(obj,df,digits=5){ >>>> if (!is.na("obj$spec$Fisher")) Fisher<-obj$spec$Fisher >>>> ... >>>> } >>>> >>>> This works when "Fisher" is defined in/passed from obj. When it >>> is not, I get error: >>>> >>>> Error in (!is.na("obj$spec$Fisher")) & Fisher : >>>> operations are possible only for numeric, logical or complex types >>>> >>>> I tried exist(Fisher), missing(Fisher)... to no vail. Any idea? Thanks.Ben Tupper Bigelow Laboratory for Ocean Sciences 60 Bigelow Drive, P.O. Box 380 East Boothbay, Maine 04544 http://www.bigelow.org