Reputation: 525
Let us say we want to calculate a certain percentage of a number, e.g. 50% of 80,000. We can of course write a quick calculation, e.g.:
> 80000 / 100 * 50
[1] 40000
Since I don't calculate percentages very often, I find that every time I have to calculate one I have to spend a couple of seconds reminding myself how to calculate it. And every time I have to calculate one I wonder if there isn't a quick function inbuilt into R that saves my lazy mind from having to do that mental gymnastics. So, is there? Something like:
percent(50, 80000)
I would also find code more comprehensible that way. My more verbally than mathematically inclined mind can immediately understand what percent(50, dat$foo)
does, while there is one cognitive step more to do for me in dat$foo / 100 * 50
.
I know I can define my own functions. That's not what I'm asking.
Note
If you think a percentage is too simple to calculate to deserve its own function, note that there are other very simple calculations built-in to Base R such as mean(x)
, which is no more complicated than sum(x) / length(x)
, so wouldn't really deserve it's own function, either.
Upvotes: 1
Views: 97
Reputation: 44957
@SamR gives a good answer using an infix operator. If you tend to use pipes, infix operators aren't so convenient, so here's a suggestion for that case.
Your function needs two arguments, and pipes generally pipe one argument in to the function, and specify other arguments explicitly. So you need to decide whether the percentage is likely to be piped in, or the value you want to compute a percentage of. I'd guess it's the latter, e.g. you want to compute 50% of each of a vector of numbers more than you want to calculate a vector of percents of one (or more) numbers.
If my guess is correct, then you should specify the values first, and the percentage second, e.g.
percent <- function(value, percentage) {
value*percentage/100
}
so that you can use it as
1:10 |> percent(10)
to get 10 percent of each value.
If you want to pipe percentages into the function, you can use the _
placeholder:
c(10, 20, 30) |> percent(x, percentage = _)
which would give 10%, 20% and 30% of a variable x
. (Here x
should probably be a scalar or length 3.)
Upvotes: 2
Reputation: 20494
The comments are getting a little much and this is a little long for one. I think this base R function does not exist. According to Meta, this is only an acceptable answer if it can be proven that this is the case. I'm not sure how to prove a negative. If you feel strongly, feel free to flag as Not An Answer.
I understand your issue and I don't think you need to justify or defend why something written out in words is easier to comprehend than the equivalent calculation, even if this is not the case for others. This is the whole basis of literate programming and avoiding magic numbers.
If you're going to define a function for this calculation, as several comments point out, it should not be called percent()
. I would use an infix operator here:
`%of%` <- \(lhs, rhs) rhs * (lhs / 100)
I think it makes it clearest what is going on:
50 %of% 80000
# [1] 40000
10 %of% 200
# [1] 20
50 %of% c(2, 4, 6)
# [1] 1 2 3
It has been suggested you define a function which you can add to your .Rprofile
. I, personally, would not. It means your code is not reproducible. I limit my .Rprofile
to things like display options, such as how many rows to print. Instead, you could create a small, local package of utility functions. If this is how you like to write code it is likely that the list of functions will grow over time. I think this is how gtools
started and I use it frequently (though you would not need to publish your package). This can be done in a few minutes these days with (the terribly named) usethis
.
Upvotes: 4