我有以下小标题:
# A tibble: 1,100 x 3
income minimum maximum
<dbl> <dbl> <dbl>
1 NA NA NA
2 0 0 25
3 0 0 25
4 NA NA NA
5 4 100 200
Run Code Online (Sandbox Code Playgroud)
我想在这些遵循均匀分布的假设下模拟最小值和最大值的值。
知道如何做到这一点吗?模拟值应出现在变量收入下的右侧。
这可能是你正在寻找的:
df$salary <- runif(nrow(df)) * (df$upperboundary - df$lowerboundary) + df$lowerboundary
Run Code Online (Sandbox Code Playgroud)
runif默认间隔为 0-1。通过此操作,您可以将其转换为您的边界。这是最快的解决方案。
随着dplyr如果你的代码是tidyverse导向:
df %>% mutate(salary = runif(n()) * (upperboundary - lowerboundary) + lowerboundary)
Run Code Online (Sandbox Code Playgroud)
但是,也可以直接定义边界:
df$salary <- runif(nrow(df), df$lowerboundary, df$upperboundary)
Run Code Online (Sandbox Code Playgroud)
如果您没有 NA,这将是最佳和最快的解决方案。无论如何,它是最具可读性的。[感谢@user20650 的帮助!]
额外细节。
这是如何运作的?
runif(nrow(df)) * (df$upperboundary - df$lowerboundary) + df$lowerboundary
Run Code Online (Sandbox Code Playgroud)
让我们看看 1,让我们手动定义最大值和最小值。
默认情况下runif(1)等于:
runif(1, min = 0, max = 1)
Run Code Online (Sandbox Code Playgroud)
因此,它根据均匀分布返回一个介于 0 和 1 之间的随机数。
要返回两个不同限制之间的随机数,例如min = 10和max = 20,您可以这样做:
runif(1, min = 10, max = 20)
Run Code Online (Sandbox Code Playgroud)
或者
min <- 10
max <- 20
runif(1, min = 0, max = 1) * (max - min) + min
Run Code Online (Sandbox Code Playgroud)
如果 runif 的输出为 0:
0 * (20 - 10) + 10
==> 10
Run Code Online (Sandbox Code Playgroud)
如果 runif 的输出为 1:
1 * (20 - 10) + 10
==> 20 - 10 + 10
==> 20
Run Code Online (Sandbox Code Playgroud)
这里还有一个替代dplyr解决方案apply:
library(dplyr)
df %>%
rowwise() %>%
mutate(salary = runif(1, lowerboundary, upperboundary)) %>%
ungroup()
Run Code Online (Sandbox Code Playgroud)
这是速度比较。“数学”是最快的:
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
Run Code Online (Sandbox Code Playgroud)