[R] How to use curve() function without using x as the variable name inside expression?

Ben Tupper ben.bighair at gmail.com
Sat Jan 31 15:39:16 CET 2015


Hi Philippe,

Ah!  Thanks for pointing out the pesky ifelse() issue.  I have only recently been learning (the hard way) that ifelse() is not a tool for the uninformed like me, but it is ever so tempting!

I would like to offer another way to speed things up. findInterval() can be quite fast, and the speed up is most noticeable when the size of the input grows (note I made input x <- 1:3000).

func <- function (x, mn, mx) 1/(mx-mn) * (x >= mn & x <= mx)

funcIfElse <- function (x, mn, mx) ifelse(x < mn | x > mx, 0, 1/(mx - mn))

funcFindInterval <- function(x, mn, mx)  1/(mx - mn) * (findInterval(x, c(mn, mx), rightmost.closed = TRUE) == 1)
        
mn<- 100; mx <- 200; x <- 1:3000
microbenchmark::microbenchmark(func(x, mn, mx), funcIfElse(x, mn, mx), funcFindInterval(x, mn, mx))

#Unit: microseconds
#                        expr     min      lq      mean   median       uq      max neval
#             func(x, mn, mx)  74.920  76.006  88.57119  76.5635  78.7065  897.333   100
#       funcIfElse(x, mn, mx) 728.388 733.206 832.02225 735.4280 796.1910 1645.804   100
# funcFindInterval(x, mn, mx)  33.954  35.334  56.57323  36.5010  38.3340  993.193   100

r1 <- func(x, mn, mx)
r2 <- funcIfElse(x, mn, mx)
r3 <- funcFindInterval(x, mn, mx)

identical(r1, r2)
#[1] TRUE
identical(r2, r3)
#[1] TRUE

Cheers,
Ben


On Jan 31, 2015, at 4:03 AM, Philippe Grosjean <phgrosjean at sciviews.org> wrote:

> Also note that ifelse() should be avoided as much as possible. To define a piecewise function you can use this trick:
> 
> func <- function (x, min, max) 1/(max-min) * (x >= min & x <= max)
> 
> The performances are much better. This has no impact here, but it is a good habit to take in case you manipulate such kind of functions in a more computing-intensive context (numerical integration, nls(), etc.).
> 
> funcIfElse <- function (x, min, max) ifelse(x < min | x > max, 0, 1/(max - min))
> min <- 100; max <- 200; x <- 1:300
> microbenchmark::microbenchmark(func(x, min, max), funcIfElse(x, min, max))
> ## Unit: microseconds
> ##                                     expr    min       lq      mean  median       uq      max neval
> ##             func(x, min, max) 10.242  16.0175  18.43348  18.446  19.8680   47.266   100
> ##  funcIfElse(x, min, max) 90.386 125.1605 148.18555 143.455 148.6695 1203.292   100
> 
> Best,
> 
> Philippe Grosjean
> 
>> On 31 Jan 2015, at 09:39, Rolf Turner <r.turner at auckland.ac.nz> wrote:
>> 
>> On 31/01/15 21:10, C W wrote:
>>> Hi Bill,
>>> 
>>> One quick question.  What if I wanted to use curve() for a uniform
>>> distribution?
>>> 
>>> Say, unif(0.5, 1.3), 0 elsewhere.
>>> 
>>> My R code:
>>> func <- function(min, max){
>>>  1 / (max - min)
>>> }
>>> 
>>> curve(func(min = 0.5, max = 1.3), from = 0, to = 2)
>>> 
>>> curve() wants an expression, but I have a constant.   And I want zero
>>> everywhere else.
>> 
>> Well if that's what you want, then say so!!!
>> 
>> func <- function(x,min,max) {
>>  ifelse(x < min | x > max, 0, 1/(max - min))
>> }
>> 
>> curve(func(u,0.5,1.3),0,2,xname="u")
>> 
>> Or, better (?) curve(func(u,0.5,1.3),0,2,xname="u",type="s")
>> 
>> which avoids the slight slope in the "vertical" lines.
>> 
>> cheers,
>> 
>> Rolf Turner
>> 
>> -- 
>> Rolf Turner
>> Technical Editor ANZJS
>> Department of Statistics
>> University of Auckland
>> Phone: +64-9-373-7599 ext. 88276
>> Home phone: +64-9-480-4619
>> 
>> ______________________________________________
>> 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.
> 
> ______________________________________________
> 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.



More information about the R-help mailing list