[英]Exponential distribution in R
我想模擬來自exp(1)分布的一些數據,但是它們必須> 0.5。所以我使用了while循環,但是它似乎不像我想要的那樣工作。在此先感謝您的回答!
x1<-c()
w<-rexp(1)
while (length(x1) < 100) {
if (w > 0.5) {
x1<- w }
else {
w<-rexp(1)
}
}
1)問題中的代碼存在以下問題:
我們在每次迭代中都需要一個新的隨機變量,但如果if
條件為FALSE,它只會生成新的隨機變量
x1
被反復覆蓋而不是擴展
盡管while
可以使用repeat
但repeat
似乎更好,因為在末尾進行測試比在開始時進行測試更合適
我們可以這樣解決:
x1 <- c()
repeat {
w <- rexp(1)
if (w > 0.5) {
x1 <- c(x1, w)
if (length(x1) == 100) break
}
}
1a)以下是一個變體。 請注意, if
沒有else
分支,則條件為FALSE的if評估為NULL,因此,如果在標記##的行上條件為FALSE,則沒有任何內容串聯到x1
。
x1 <- c()
repeat {
w <- rexp(1)
x1 <- c(x1, if (w > 0.5) w) ##
if (length(x1) == 100) break
}
2)或者,這會生成200個指數隨機變量,僅保留那些大於0.5的變量。 如果生成的數量少於100,請重復。 最后,它從最后一個生成的批次中提取前100個。 我們選擇了200,使其足夠大,以便在大多數運行中僅需要循環的一次迭代。
repeat {
r <- rexp(200)
r <- r[r > 0.5]
if (length(r) >= 100) break
}
r <- head(r, 100)
備選方案(2)實際上比(1)或(1a)更快,因為它的矢量化程度更高。 盡管它比其他解決方案丟掉了更多的指數隨機變量。
我建議不要使用while
(或任何其他接受/拒絕)循環。 而是使用truncdist
的方法:
# Sample 1000 observations from a truncated exponential
library(truncdist);
x <- rtrunc(1000, spec = "exp", a = 0.5);
# Plot
library(ggplot2);
ggplot(data.frame(x = x), aes(x)) + geom_histogram(bins = 50) + xlim(0, 10);
使用逆變換采樣實現采樣器也很簡單,它可以從截斷的指數分布中抽取采樣,從而避免在循環中拒絕采樣。 這將是一種比任何基於接受/拒絕的采樣方法更為有效的方法,並且在您的情況下效果特別好,因為存在截斷指數cdf的封閉形式。 例如,請參閱此帖子以獲取更多詳細信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.