簡體   English   中英

如何將隨機分布轉換為 R 中的(預定義)integer 值?

[英]How can i transform random distribution to (predefined) integer values in R?

在 R 中有很多樣本,我可以根據特定分布生成模擬數據。 例如:

rnorm(N, 0, 1)
runif(N, 0, 1)

這給了我一組基本上是實數的隨機值。 但是,出於某種原因,我想獲得基於一組整數的結果,例如從 1 到 10 的整數,例如 c(1:10)。

是否有任何簡單的 function 可以轉換,例如獲得的實際值的正態分布到 integer 值的指示范圍的(偽)正態分布?

編輯:在社會科學中,觀察到的變量通常是問卷分數。 這些問卷的結果以 integer 數字計分。 該科目不能得1.5分,只有1分或2分。 然而,可以得到結果的正態分布。 我正在尋找在 integer 結果中生成這樣的分布的 function。

其他背景:標准十級將一系列標准化結果轉換為 integer 范圍。 我正在為任何分布和任何“支架”范圍尋找類似的 function。

要將任何實值變量(包括來自連續分布的樣本)分箱,您可以使用 cut,然后將生成的因子變量轉換為 integer 變量。

如果您希望轉換為標准十分數,則切割 function 中的中斷將基於 Z 分數,在標准正態的情況下是樣本值。

# Generate the binned variable:
as.integer(cut(rnorm(1000), breaks=c(-Inf, -2, -1.5, -1, -0.5, 0, 0.5, 1, 1.5, 2, Inf)))
# Distribution of the binned variable:
table(cut(rnorm(1000), breaks=c(-Inf, -2, -1.5, -1, -0.5, 0, 0.5, 1, 1.5, 2, Inf)))

對於從 0 到 1 的統一 RV,生成 10 級離散 RV 並檢查其分布的相應代碼可能是:

as.integer(cut(runif(1000), breaks=c(-Inf, 1:9*0.1, Inf)))
table(cut(runif(1000), breaks=c(-Inf, 1:9*0.1, Inf)))

一般來說,您需要決定休息時間(垃圾箱的邊界)。 這是一個概念問題。 您可以選擇使用您要采樣的分布的屬性(如標准 10 的情況)。 或者您可以使用樣本的分布。 如果您希望使用樣本的分布,那么分位數 function 可能有用。

為了完整起見,請注意分箱的連續 rv 是離散的分類 rv,其中每個級別的出現概率對應於箱。 在簡單的情況下,如果您將連續制服分為 10 個大小相等的箱,則生成的離散變量是具有 10 個事件且每個事件的概率相等的分類變量。 在標准 Normal 和標准 10 的情況下,可以使用 cdf 生成每次中斷的概率。 例如,(-Inf, -2] 的概率是pnorm(-2) - pnorm(-Inf) ,依此類推,用於各種中斷。這些值可用於將標准 10 分數分布定義為分類分布使用上面的計算值分布每個事件的概率。有關從分類中采樣的函數,請參見 package extraDists

二項分布固定為離散且固定數量的值,並近似於正態分布:

y <- table(rbinom(500, 10, prob = .5))
x <- dimnames(y)[[1]]
y <- as.integer(y)
plot(x = x, y = y, type = "h")
points(x, y, pch = 15)

在此處輸入圖像描述

在嘗試了許多不同的選項之后,我決定解決我的問題的方法是簡單地將獲得的隨機變量轉換為不同的范圍並對其進行四舍五入。 為此,我創建了另一篇關於轉換的文章,並使用了另一篇文章中的轉換 function。 這使我可以通過簡單地將其調整到不同的最大值和最小值范圍來粗略地保持給定變量及其屬性的分布。 這也允許我使用任何隨機分布作為輸入參數。

# this is scale function by Allan Cameron, see other post linked
linscale_to_int <- function(y, x) (x - min(x)) * (y - 1) / diff(range(x)) + 1

# you can try any of this distribution
# x.rand <- rnorm(500,0,1)
# x.rand <- runif(50, 0, 1)
x.rand <- rnorm(100)
# let's change scope of variable
y.rand <- linscale_to_int(20,x.rand)
# and then we can round it
y.round <- round(y.rand)
# we may check it's distibution by plot
x.pl <- dimnames(table(y.round))[[1]]
y.pl <- as.integer(table(y.round))
plot(x = x.pl, y = y.pl, type = "h")
# or check it with test
shapiro.test(y.round)

注意:並非該算法的每次重復都會產生完全令人滿意的效果,因為當隨機選擇小樣本時,可能總是會發生舍入不允許創建分布與正態分布非常相似的變量的情況。 但無論如何它對我有用。 或者 - 一個可以隨機循環,然后得到最好的一個(具有最大的 shapiro.test$p.value 的 p 值)

感謝大家提供的解決方案!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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