# [R] Breakdown a number

Gabor Grothendieck ggrothendieck at gmail.com
Thu Apr 20 14:34:37 CEST 2006

```Try using breaks[breaks <= x] in place of breaks.   Your solution
always returns three components if breaks has two whereas this one
does not but you could extend the output it if that is an essential part.

On 4/20/06, Paul Roebuck <roebuck at mdanderson.org> wrote:
> On Thu, 20 Apr 2006, Gabor Grothendieck wrote:
>
> > On 4/19/06, Paul Roebuck <roebuck at mdanderson.org> wrote:
> > > On Wed, 19 Apr 2006, Gabor Grothendieck wrote:
> > >
> > > > On 4/19/06, Paul Roebuck <roebuck at mdanderson.org> wrote:
> > > >
> > > > > Isn't there a builtin method for doing this and, if so,
> > > > > what is it called?
> > > > >
> > > > >        breakdown <- function(whole) {
> > > > >            breaks <- c(250, 800)
> > > > >            pieces <- integer(length(breaks) + 1)
> > > > >            if (whole > breaks[2]) {
> > > > >                pieces[3] <- whole - breaks[2]
> > > > >                whole <- breaks[2]
> > > > >            }
> > > > >            if (whole > breaks[1]) {
> > > > >                pieces[2] <- whole - breaks[1]
> > > > >                whole <- breaks[1]
> > > > >            }
> > > > >            pieces[1] <- whole
> > > > >
> > > > >            return(pieces)
> > > > >        }
> > > > >
> > > > > breakdown(1200) # 250 550 400
> > > >
> > > > Maybe you could discuss in words what you want but perhaps
> > > > you are looking for diff:
> > >
> > > That was rather my problem searching for my answer as I
> > > was unsure what this was called. I was searching for
> > > 'bins' or 'breaks' (like in hist method but not for
> > > plotting) and leading nowhere fast. Alas, I thought
> > > sample code would go further than my description.
> > >
> > >
> > > > > bp <- c(0, 250, 800, 1200)
> > > > > diff(bp)
> > > > [1] 250 550 400
> > >
> > > Don't think diff method is going to work either, at
> > > least in cases where the 'whole' is less than greatest
> > > 'break'.
> > >
> > > > breakdown2 <- function(x, breaks = c(250, 800)) {
> > >      diff(c(0, breaks, x))
> > >  }
> > > > breakdown(10)         # 10 0 0
> > > > breakdown2(10)        # 250 550 -790
> > > >
> > > > breakdown(400)        # 250 150 0
> > > > breakdown2(400)       # 250 550 -400
> > >
> >
> > Just sort it:
> >
> > bd <- function(x, breaks = c(250, 800)) diff(sort(c(0, breaks, x)))
>
> Doesn't work either. Tests below didn't fare well.
>
> > If you don't want the 0 values in the case that x is one of the
> > breaks then use diff(sort(unique(c(0, breaks, x))))
>
> I did want the zeros in the result.
>
> ###
> check.results <- function(input) {
>    stopifnot(input >= 0)
>    output <- bd(input)
>    expected <- breakdown(input)
>    if (!identical(output, expected)) {
>        cat("expected:", expected, "\n")
>        cat("output:  ", output,   "\n")
>        return(FALSE)
>    } else {
>        return(TRUE)
>    }
> }
>
> check.results(1200)     # TRUE
> check.results(800)      # TRUE
> check.results(799)      # FALSE
> check.results(500)      # FALSE
> check.results(250)      # FALSE
> check.results(200)      # FALSE
> check.results(1)        # FALSE
> check.results(0)        # FALSE
>
> Goal was to split value according to breaks such that each
> piece of it could later be multiplied with a corresponding
> rate. It's not unlike the type of processing that would go
> into figuring out how much a hypothetical out-of-state phone
> call would cost (for example, .10 for first five minutes,
> 0.07 for next ten minutes, and 0.05 for rest of the call)
>
> calc.cost.per.call <- function(minutes) {
>    duration <- bd(minutes, breaks = c(5, 10))
>    rates <- c(0.10, 0.07, 0.05)
>    sum(duration * rates)
> }
>
> calc.cost.per.call(24)  # would be 1.65
>
>
>
> ----------------------------------------------------------
> SIGSIG -- signature too long (core dumped)
>
> ______________________________________________
> R-help at stat.math.ethz.ch mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help