首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在定义的范围内生成具有定义相关性的R中的随机值

在定义的范围内生成具有定义相关性的R中的随机值
EN

Stack Overflow用户
提问于 2017-07-03 14:14:29
回答 2查看 1K关注 0票数 0

对于一个科学项目,我正在寻找一种在一定范围内产生随机数据的方法(例如,min=0,max=100000),它与另一个已经存在于R中的变量有一定的相关性。我们的目标是稍微丰富数据集,以便生成一些更有意义的图表(不用担心,我正在处理虚构的数据)。

例如,我想用以下数据生成与r=-.78相关的随机值:

代码语言:javascript
运行
复制
var1 <- rnorm(100, 50, 10)

我已经遇到了一些很好的解决方案(即https://stats.stackexchange.com/questions/15011/generate-a-random-variable-with-a-defined-correlation-to-an-existing-variable),但是只得到了非常小的值,而这些值我无法转换,因此在其他原始值的上下文中是有意义的。

如下所示:

代码语言:javascript
运行
复制
var1 <- rnorm(100, 50, 10)
n     <- length(var1)                   
rho   <- -0.78                   
theta <- acos(rho)             
x1    <- var1      
x2    <- rnorm(n, 50, 50)      
X     <- cbind(x1, x2)         
Xctr  <- scale(X, center=TRUE, scale=FALSE)   

Id   <- diag(n)                               
Q    <- qr.Q(qr(Xctr[ , 1, drop=FALSE]))       
P    <- tcrossprod(Q)          # = Q Q'       
x2o  <- (Id-P) %*% Xctr[ , 2]                 
Xc2  <- cbind(Xctr[ , 1], x2o)                
Y    <- Xc2 %*% diag(1/sqrt(colSums(Xc2^2)))  
var2 <- Y[ , 2] + (1 / tan(theta)) * Y[ , 1]    
cor(var1, var2)  

我得到的var2值在-0.5到0.5之间。平均值为0。我希望有更多的分布式数据,所以我可以简单地通过添加50来转换它,并且与我的第一个变量有相当相似的范围。

你们中有谁知道如何生成这类或多或少的-meaningful数据吗?

提前谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-03 17:02:21

var1开始,重命名为A,并使用10,000个点:

代码语言:javascript
运行
复制
set.seed(1)
A <- rnorm(10000,50,10)  # Mean of 50

首先,将A中的值转换为具有新的所需均值50,000并具有逆关系(即减去):

代码语言:javascript
运行
复制
B <- 1e5 - (A*1e3) # Note that { mean(A) * 1000 = 50,000 }

这只会导致r = -1。添加一些噪声以实现所需的r

代码语言:javascript
运行
复制
B <- B + rnorm(10000,0,8.15e3) # Note this noise has mean = 0
                               # the amount of noise, 8.15e3, was found through parameter-search

这有您想要的相关性:

代码语言:javascript
运行
复制
cor(A,B)
[1] -0.7805972

意见如下:

代码语言:javascript
运行
复制
plot(A,B)

警诫

您的B值可能超出您的范围0 100,000。如果使用不同的种子或生成更多的数字,则可能需要筛选超出范围的值。

尽管如此,目前的范围很好:

代码语言:javascript
运行
复制
range(B)
[1]  1668.733 95604.457
票数 0
EN

Stack Overflow用户

发布于 2017-07-03 14:30:19

如果您对生成值的相关性和边缘分布(即形状)感到满意,那么将这些值(介于(-.5,+5)之间)乘以100,000并添加50,000。

代码语言:javascript
运行
复制
> c(-0.5, 0.5) * 100000 + 50000
[1] 0e+00 1e+05

编辑:这种方法,或任何其他东西,其中10万&5万被交换为不同的数字,将是一个“线性转换”的例子,由@gregor-de-cillia推荐。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44887827

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档