Alberto Vieira Ferreira Monteiro
2006-Oct-07 12:38 UTC
[R] ifelse(logical, function1, function2) does not work
Why this kind of assignment does not work? n <- 1 f <- ifelse(n == 1, sin, cos) f(pi) this must be rewritten as: n <- 1 f <- cos if (n == 1) f <- sin f(pi) [oops. 1.224606e-16 instead of zero. Damn floating point errors :-/] Alberto Monteiro
Gabor Grothendieck
2006-Oct-07 12:55 UTC
[R] ifelse(logical, function1, function2) does not work
Try n <- 1 f <- if (n == 1) sin else cos f(pi) On 10/7/06, Alberto Vieira Ferreira Monteiro <albmont at centroin.com.br> wrote:> Why this kind of assignment does not work? > > n <- 1 > f <- ifelse(n == 1, sin, cos) > f(pi) > > this must be rewritten as: > > n <- 1 > f <- cos > if (n == 1) f <- sin > f(pi) > > [oops. 1.224606e-16 instead of zero. Damn floating point errors :-/] > > Alberto Monteiro > > ______________________________________________ > R-help at stat.math.ethz.ch 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. >
Peter Dalgaard
2006-Oct-07 13:01 UTC
[R] ifelse(logical, function1, function2) does not work
Alberto Vieira Ferreira Monteiro <albmont at centroin.com.br> writes:> Why this kind of assignment does not work? > > n <- 1 > f <- ifelse(n == 1, sin, cos) > f(pi)It's not supposed to. 'ifelse' returns a value with the same shape as 'test' which is filled with elements selected from either 'yes' or 'no' depending on whether the element of 'test' is 'TRUE' or 'FALSE'. which makes very little sense if yes and no are functions.> this must be rewritten as: > > n <- 1 > f <- cos > if (n == 1) f <- sin > f(pi)No, it must not. n <- 1 f <- if (n==1) sin else cos f(pi) or even (if (n==1) sin else cos)(pi) -- O__ ---- Peter Dalgaard ?ster Farimagsgade 5, Entr.B c/ /'_ --- Dept. of Biostatistics PO Box 2099, 1014 Cph. K (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk) FAX: (+45) 35327907
Peter Dalgaard writes:> Alberto Vieira Ferreira Monteiro <albmont at centroin.com.br> writes: > > > Why this kind of assignment does not work? > > > > n <- 1 > > f <- ifelse(n == 1, sin, cos) > > f(pi) > > It's not supposed to. > > 'ifelse' returns a value with the same shape as 'test' which is > filled with elements selected from either 'yes' or 'no' depending > on whether the element of 'test' is 'TRUE' or 'FALSE'. > > which makes very little sense if yes and no are functions.I think that's a debatable assertion. Why might I not want a vector, or rather a list, of functions? (Mr. Monteiro's real sin is a very common one --- using ifelse() unnecessarily/inappropriately, i.e. when the ``test'' argument is a scalar.) But to get back to trying to apply ifelse() with functions for the ``yes'' and ``no'' arguments: What's happening is really a feature of the ***rep()*** function, and the way that it treats objects of different natures. If you do rep(1,5) you get a vector of 5 1's. If you do rep(sin,5) you get an error message. Note however that if you do > x <- list(a=17,b=42) > junk <- rep(x,5) then junk is a list of length 5, each entry of which is a copy of x. I.e. rep() works as expected (?) with lists. And if you make the assignments > y <- list(a=42,b=17) > n <- 1 and then execute > ifelse(n==1,x,y) you get a copy of x. So rep does its thing with numbers (and vectors) and lists, but not with *functions*. What else might one try to rep? What about matrices? Works, but the matrix is coerced to a vector first. One might have naively hoped that rep(M,5) would yield a list of length 5, each entry of which was a copy of M. But it doesn't; it gives a vector of length 5*nrow(M)*ncol(M) consisting of the data of M strung out in column order, 5 times over. The function rep() seems to have (S3) methods associated with it --- rep.Date, rep.factor, etc., but no generic function. I.e. rep() does not seem to dispatch methods. Nor is there a rep.default(). I wrote a ``method'' for the matrix class rep.matrix <- function(x,times) { if(!inherits(x,"matrix")) stop("Argument x is not a matrix.\n") ans <- list() ans[1:times] <- list(x) ans } That seemed to give the result I expected/wanted; rep(M,5) did indeed give a list of length 5, each entry of which was a copy of M. However a similar ``method'' for functions did not work; rep(sin,5) gave the same old ``object is not subsettable'' error. But if I called rep.function() *explicitly* I got what I wanted. I.e. > rep.function(sin,5) gave a list of length 5 each entry of which was ``.Primitive("sin")''. Questions: How do methods for rep() get dispatched when there is no generic rep()? How come the matrix method that I wrote got dispatched, but the function method didn't? cheers, Rolf Turner rolf at math.unb.ca