This is probably what you're looking for:
df$salary <- runif(nrow(df)) * (df$upperboundary - df$lowerboundary) + df$lowerboundary
runif default interval is 0-1. With this operation you transform it to your boundaries. It is the fastest solution.
With dplyr if your code is tidyverse oriented:
df %>% mutate(salary = runif(n()) * (upperboundary - lowerboundary) + lowerboundary)
However, it is also possible to define the boundaries directly:
df$salary <- runif(nrow(df), df$lowerboundary, df$upperboundary)
If you had no NAs, this one would be the optimal and fastest solution.
It is anyway the most readable. [Thanks to @user20650 for your help!]
Additional details.
How does this work?
runif(nrow(df)) * (df$upperboundary - df$lowerboundary) + df$lowerboundary
Let's look at 1 and let's define manually a max and a min.
By default runif(1) is equal to:
runif(1, min = 0, max = 1)
Therefore, it return a random number between 0 and 1 according to a uniform distribution.
To return a random number between two different limits, say for instance min = 10 and max = 20, you can do it this way:
runif(1, min = 10, max = 20)
or
min <- 10
max <- 20
runif(1, min = 0, max = 1) * (max - min) + min
if the output of runif is 0:
0 * (20 - 10) + 10
==> 10
if the output of runif is 1:
1 * (20 - 10) + 10
==> 20 - 10 + 10
==> 20
Here also an alternative with dplyr to the solution with apply:
library(dplyr)
df %>%
rowwise() %>%
mutate(salary = runif(1, lowerboundary, upperboundary)) %>%
ungroup()
Here's a speed comparison. The "maths" one is the fastest:
microbenchmark::microbenchmark(
apply = apply(df[-1],1, function(x) runif(1, x[1], x[2])),
maths = runif(nrow(df)) * (df$upperboundary - df$lowerboundary) + df$lowerboundary,
maths2 = runif(nrow(df), df$lowerboundary, df$upperboundary),
dplyr = df %>% rowwise() %>% mutate(runif = runif(1, lowerboundary, upperboundary)) %>% ungroup()
)
#> Unit: microseconds
#> expr min lq mean median uq max neval
#> apply 907.1 955.90 1175.188 1023.70 1280.90 4455.0 100
#> maths 16.8 26.05 32.651 31.25 38.65 75.0 100
#> maths2 117.8 128.00 156.533 136.60 175.15 336.7 100
#> dplyr 1424.2 1496.60 1821.068 1661.15 1989.20 3952.7 100