簡體   English   中英

R中的指數分布

[英]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可以使用repeatrepeat似乎更好,因為在末尾進行測試比在開始時進行測試更合適

我們可以這樣解決:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM