假设这些都是均匀分布的,如何从下边界和上边界模拟 R 中的值?

vah*_*100 3 statistics r

我有以下小标题:

# 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)

我想在这些遵循均匀分布的假设下模拟最小值和最大值的值。

知道如何做到这一点吗?模拟值应出现在变量收入下的右侧。

Edo*_*Edo 5

这可能是你正在寻找的:

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 = 10max = 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)