Hello everybody I have a generic problem which the following toy function illustrates: f <- function(n) { if(abs(n) < pi) { return(TRUE) } else { return(FALSE) } } I want it to return TRUE if abs(n)<pi and FALSE otherwise. f() is fine as far as it goes, but does not deal well with NA or NaN or NULL (I want these to signal some problem with the argument (ie return FALSE), but not to stop execution of f(). In particular, I want f() to pass R CMD check )-: R> f(NA) Error in if (abs(n) < pi) { : missing value where logical needed R> f(NULL) Error in abs(n) : non-numeric argument to function So, how best to patch f() up? The best I could come up with was: f2 <- function(n) { if(is.null(n)){return(FALSE)} if(is.na(n)){return(FALSE)} if(abs(n) < pi) { return(TRUE) } else { return(FALSE) } } This can't be the best way! Anyway, f2() isn't right: f2(numeric(0)) fails; note that R> if(is.na(numeric(0))){print("asdf")} falls over. help.search("trap") was not very helpful. try() doesn't help either: R> try(if(1==NA){print("asdf")}) Error in if (1 == NA) { : missing value where logical needed QUESTION: how to make f() not give an error under any circumstances? -- Robin Hankin, Lecturer, School of Geography and Environmental Science Tamaki Campus Private Bag 92019 Auckland New Zealand r.hankin at auckland.ac.nz tel 0064-9-373-7599 x6820; FAX 0064-9-373-7042
How about: > f3 <- function(n){ + n.pi <- (abs(n)<pi) + n.pi[is.na(n.pi)] <- F + n.pi + } > > f3(c(1, 5, NA)) [1] TRUE FALSE FALSE > Spencer Graves Robin Hankin wrote:> Hello everybody > > > I have a generic problem which the following toy function illustrates: > > f <- function(n) { > if(abs(n) < pi) { > return(TRUE) > } else { > return(FALSE) > } > } > > I want it to return TRUE if abs(n)<pi and FALSE otherwise. f() is > fine as far as it goes, but does not deal well with NA or NaN or NULL > (I want these to signal some problem with the argument (ie return > FALSE), but not to stop execution of f(). In particular, I want f() > to pass R CMD check )-: > > R> f(NA) > Error in if (abs(n) < pi) { : missing value where logical needed > > R> f(NULL) > Error in abs(n) : non-numeric argument to function > > > So, how best to patch f() up? The best I could come up with was: > > f2 <- function(n) { > if(is.null(n)){return(FALSE)} > if(is.na(n)){return(FALSE)} > if(abs(n) < pi) { > return(TRUE) > } else { > return(FALSE) > } > } > > This can't be the best way! Anyway, f2() isn't right: f2(numeric(0)) > fails; note that > > R> if(is.na(numeric(0))){print("asdf")} > > falls over. help.search("trap") was not very helpful. try() doesn't > help either: > > R> try(if(1==NA){print("asdf")}) > Error in if (1 == NA) { : missing value where logical needed > > > > QUESTION: how to make f() not give an error under any circumstances? > > > > > >
Try: f <- function(n) { if(is.null(n) || is.na(n) || abs(n) < pi) { return(FALSE) } else { return(TRUE) } } Note that the order of the conditions inside if() matters: is.na(n) only gets evaluated if is.null(n) is FALSE, and so on. Andy> -----Original Message----- > From: Robin Hankin [mailto:r.hankin at auckland.ac.nz] > Sent: Thursday, February 13, 2003 5:36 PM > To: r-help at stat.math.ethz.ch > Subject: [R] generic handling of NA and NaN and NULL > > > Hello everybody > > > I have a generic problem which the following toy function illustrates: > > f <- function(n) { > if(abs(n) < pi) { > return(TRUE) > } else { > return(FALSE) > } > } > > I want it to return TRUE if abs(n)<pi and FALSE otherwise. f() is > fine as far as it goes, but does not deal well with NA or NaN or NULL > (I want these to signal some problem with the argument (ie return > FALSE), but not to stop execution of f(). In particular, I want f() > to pass R CMD check )-: > > R> f(NA) > Error in if (abs(n) < pi) { : missing value where logical needed > > R> f(NULL) > Error in abs(n) : non-numeric argument to function > > > So, how best to patch f() up? The best I could come up with was: > > f2 <- function(n) { > if(is.null(n)){return(FALSE)} > if(is.na(n)){return(FALSE)} > if(abs(n) < pi) { > return(TRUE) > } else { > return(FALSE) > } > } > > This can't be the best way! Anyway, f2() isn't right: f2(numeric(0)) > fails; note that > > R> if(is.na(numeric(0))){print("asdf")} > > falls over. help.search("trap") was not very helpful. try() doesn't > help either: > > R> try(if(1==NA){print("asdf")}) > Error in if (1 == NA) { : missing value where logical needed > > > > QUESTION: how to make f() not give an error under any circumstances? > > > > > > > -- > > Robin Hankin, Lecturer, > School of Geography and Environmental Science > Tamaki Campus > Private Bag 92019 Auckland > New Zealand > > r.hankin at auckland.ac.nz > tel 0064-9-373-7599 x6820; FAX 0064-9-373-7042 > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > stat.math.ethz.ch/mailman/listinfo/r-help >------------------------------------------------------------------------------
Hi Spencer thanks for this> How about: > > > f3 <- function(n){ > + n.pi <- (abs(n)<pi) > + n.pi[is.na(n.pi)] <- F > + n.pi > + } > >nope! Sometimes I need things like R> x <- 1:10 R> if(f3(x[x>11])==TRUE){print("asfd")} Error in if (f3(x[x > 11]) == TRUE) { : missing value where logical needed best rksh -- Robin Hankin, Lecturer, School of Geography and Environmental Science Tamaki Campus Private Bag 92019 Auckland New Zealand r.hankin at auckland.ac.nz tel 0064-9-373-7599 x6820; FAX 0064-9-373-7042
Hello Andy thanks for this; but R> x <- 1:10 R> f function(n) { if(is.null(n) || is.na(n) || abs(n) < pi) { return(FALSE) } else { return(TRUE) } } R> x <- 1:10 R> f(x[x>11]) Error in if (is.null(n) || is.na(n) || abs(n) < pi) { : missing value where logical needed>> > Try: > > f <- function(n) { > if(is.null(n) || is.na(n) || abs(n) < pi) { > return(FALSE) > } else { > return(TRUE) > } > } > > Note that the order of the conditions inside if() matters: is.na(n) only > gets evaluated if is.null(n) is FALSE, and so on. > > Andy >-- Robin Hankin, Lecturer, School of Geography and Environmental Science Tamaki Campus Private Bag 92019 Auckland New Zealand r.hankin at auckland.ac.nz tel 0064-9-373-7599 x6820; FAX 0064-9-373-7042
> From: Spencer Graves [mailto:spencer.graves at pdf.com] > > How about: > > > f3 <- function(n){ > + n.pi <- (abs(n)<pi) > + n.pi[is.na(n.pi)] <- F > + n.pi > + } > > > > f3(c(1, 5, NA)) > [1] TRUE FALSE FALSE > >A couple of problems: a) It chokes if argument is NULL. b) Use of F instead of FALSE will not pass R CMD check, which is what Robin wants. Andy> Spencer Graves > > Robin Hankin wrote: > > Hello everybody > > > > > > I have a generic problem which the following toy function > illustrates: > > > > f <- function(n) { > > if(abs(n) < pi) { > > return(TRUE) > > } else { > > return(FALSE) > > } > > } > > > > I want it to return TRUE if abs(n)<pi and FALSE otherwise. f() is > > fine as far as it goes, but does not deal well with NA or > NaN or NULL > > (I want these to signal some problem with the argument (ie return > > FALSE), but not to stop execution of f(). In particular, I want f() > > to pass R CMD check )-: > > > > R> f(NA) > > Error in if (abs(n) < pi) { : missing value where logical needed > > > > R> f(NULL) > > Error in abs(n) : non-numeric argument to function > > > > > > So, how best to patch f() up? The best I could come up with was: > > > > f2 <- function(n) { > > if(is.null(n)){return(FALSE)} > > if(is.na(n)){return(FALSE)} > > if(abs(n) < pi) { > > return(TRUE) > > } else { > > return(FALSE) > > } > > } > > > > This can't be the best way! Anyway, f2() isn't right: > f2(numeric(0)) > > fails; note that > > > > R> if(is.na(numeric(0))){print("asdf")} > > > > falls over. help.search("trap") was not very helpful. > try() doesn't > > help either: > > > > R> try(if(1==NA){print("asdf")}) > > Error in if (1 == NA) { : missing value where logical needed > > > > > > > > QUESTION: how to make f() not give an error under any circumstances? > > > > > > > > > > > > > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > stat.math.ethz.ch/mailman/listinfo/r-help >------------------------------------------------------------------------------
The version I gave is obviously not vectorized (since your original version seem to indicate that the argument won't have length > 1, otherwise the if() won't really make sense). Replacing is.null(n) with length(n)!=1 (or length(n)==0) should do the trick (I hope!). Andy> -----Original Message----- > From: Robin Hankin [mailto:r.hankin at auckland.ac.nz] > Sent: Thursday, February 13, 2003 6:30 PM > To: andy_liaw at merck.com > Cc: r.hankin at auckland.ac.nz; r-help at stat.math.ethz.ch > Subject: Re: [R] generic handling of NA and NaN and NULL > > > > > Hello Andy > > thanks for this; but > > > R> x <- 1:10 > R> f > function(n) { > if(is.null(n) || is.na(n) || abs(n) < pi) { > return(FALSE) > } else { > return(TRUE) > } > } > R> x <- 1:10 > R> f(x[x>11]) > Error in if (is.null(n) || is.na(n) || abs(n) < pi) { : > missing value where logical needed > > > > > > > > > > > > Try: > > > > f <- function(n) { > > if(is.null(n) || is.na(n) || abs(n) < pi) { > > return(FALSE) > > } else { > > return(TRUE) > > } > > } > > > > Note that the order of the conditions inside if() matters: > is.na(n) only > > gets evaluated if is.null(n) is FALSE, and so on. > > > > Andy > > > > > -- > > Robin Hankin, Lecturer, > School of Geography and Environmental Science > Tamaki Campus > Private Bag 92019 Auckland > New Zealand > > r.hankin at auckland.ac.nz > tel 0064-9-373-7599 x6820; FAX 0064-9-373-7042 >------------------------------------------------------------------------------