我想根据以下df对price
和est_p
(估算概率)进行模拟:
df <- data.frame(price = c(200, 100, 600, 20, 100),
est_p = c(0.9, 0.2, 0.8, 0.5, 0.6),
actual_sale = c(FALSE, TRUE, TRUE, TRUE, TRUE))
收入是-price
的总和,其中actual_sale
是TRUE
:
print(actual1 <- sum(df$price[df$actual_sale])) # Actual Revenue
[1] 820
我创建了一个函数,用于根据est_p
和price
值模拟伯努利试验:
bernoulli <- function(df) {
sapply(seq(nrow(df)), function(x) {
prc <- df$price[x]
p <- df$est_p[x]
sample(c(prc, 0), size = 1000, replace = T, prob = c(p, 1 - p))
})
}
并将其应用于示例df
:
set.seed(100)
distr1 <- rowSums(bernoulli(df))
quantile(distr1)
0% 25% 50% 75% 100%
0 700 820 920 1020
看起来不错,实际值=中位数!但是,当我将相同的函数应用于增加的样本量(重复x 1000次)df1000
时,实际收入超出了模拟值的范围:
df1000 <- do.call("rbind", replicate(1000, df, simplify = FALSE))
print(actual2 <- sum(df1000$price[df1000$actual_sale]))
[1] 820000
distr2 <- rowSums(bernoulli(df1000))
quantile(distr2)
0% 25% 50% 75% 100%
726780 744300 750050 754920 775800
为什么实际收入超出了模拟值范围?我在哪里犯了错误,正确的解决方案是什么?
答案 0 :(得分:0)
我需要一个空格来澄清我的评论,说您的rbind
中的cbind
更改为do.call
。这就是为什么我这么说。
set.seed(100)
df <- data.frame(price = c(200, 100, 600, 20, 100),
est_p = c(0.9, 0.2, 0.8, 0.5, 0.6),
actual_sale = c(FALSE, TRUE, TRUE, TRUE, TRUE))
print(actual1 <- sum(df$price[df$actual_sale])) # Actual Revenue
[1] 820
# here is where you need to change the rbind to cbind to stay within the range
# otherwise you're essentially changing the distribution of the data and you
# can't compare the results
df1000 <- do.call("cbind", replicate(1000, df, simplify = FALSE))
print(actual2 <- sum(df1000$price[df1000$actual_sale]))
[1] 820
这里是simulated
发行版,rbind
发行版和cbind
发行版,您可以看到它们。如您所见,simulated
和cbind
是相同的。 rbind
产生了不同的分布。 quantile()
或fivenum()
从分布中得出。这就是为什么您得到一个不同的数字。
希望这有助于找出quantile()
或从中获取数字的原因。