2015-02-09 115 views
1

如何創建具有彼此特定相關性的兩列的數據集?我希望能夠定義將要創建的值的數量並指定輸出應具有的相關性。R:在r中創建具有特定相關性的數據集

問題是類似於此:Generate numbers with specific correlation

答案之一是使用:

out <- mvrnorm(10, mu = c(0,0), Sigma = matrix(c(1,0.56,0.56,1),, ncol = 2), 
       mpirical = TRUE) 

生產這樣的輸出:

  [,1]   [,2] 
[1,] -0.4152618 0.033311146 
[2,] 0.7617759 -0.181852441 
[3,] -1.6393045 -1.054752469 
[4,] -1.7872420 -0.605214425 
[5,] 0.9581152 2.511000955 
[6,] 0.5048160 -0.278329145 
[7,] 0.8656220 0.483521747 
[8,] -0.1385699 0.017395548 
[9,] 0.3261103 -0.932889606 
[10,] 0.5639388 0.007808691 

與下列相關表cor(out):

​​

但我想數據設置爲含有較高,無負多遠號碼例如:具有1相關

 x y 
    1 5 5 
    2 20 20 
    3 30 30 
    4 100 100 

:遠

x y 
    x 1 1 
    y 1 1 

具有更多的I意味着「更多」隨機性和更大的價值,就像我上面的示例一樣。

是否有(簡單)的方式來歸檔類似的東西?

+1

「Pearson相關係數的一個關鍵數學特性是,分離兩個變量的位置和比例變化是不變的。」 =>爲什麼你不只是把'out'縮放到想要的範圍內呢? – Jealie 2015-02-09 18:52:05

回答

2

相關性不受底層變量的線性變換的影響。所以最直接的方式得到你想要的可能是什麼:

out <- as.data.frame(mvrnorm(10, mu = c(0,0), 
        Sigma = matrix(c(1,0.56,0.56,1),, ncol = 2), 
        empirical = TRUE)) 

out$V1.s <- (out$V1 - min(out$V1))*1000+10 
out$V2.s <- (out$V2 - min(out$V2))*200+30 

現在數據幀out已經「轉移」列V1.sV2.s這都是非負和「大」。你可以使用任何你想要的數字,而不是上面代碼中的1000,10,200和30。相關的答案仍然是0.56。

> cor(out$V1.s, out$V2.s) 
[1] 0.56 
+0

非常感謝,它可以像影像一樣工作! 你也許知道我可以如何歸檔類似的東西,而只是整數(正整數)? – Deset 2015-02-09 19:10:15

+1

Deset,如果我的答案有幫助,請考慮接受或至少upvoting它。要製作數字整數,我不知道確切的方法,但可以通過簡單地轉換爲大範圍,然後舍入到最接近的整數來近似所需的相關係數。 – 2015-02-09 19:53:14

+1

注意舍入會稍微增加你的方差(例如'var(floor(rnorm(1000000)))'大約是1.08,而var(rnorm(1000000))大約是1.你可能會發現[this link] //www.sitmo.com/article/generating-correlated-random-numbers/)有幫助 – Jthorpe 2015-02-09 20:03:30

1

謝謝Curt F.這對我來說有助於生成一些模擬數據集。我添加了一些選項來指定約。 X和Y所需的平均值和範圍。它還提供輸出,以便您可以檢查斜率和截距以及繪製點和迴歸線。

library(MASS) 
library(ggplot2) 
# Desired correlation 
d.cor <- 0.5 
# Desired mean of X 
d.mx <- 8 
# Desired range of X 
d.rangex <- 4 
# Desired mean of Y 
d.my <- 5 
# Desired range of Y 
d.rangey <- 2 
# Calculations to create multipliation and addition factors for mean and range of X and Y 
mx.factor <- d.rangex/6 
addx.factor <- d.mx - (mx.factor*3) 
my.factor <- d.rangey/6 
addy.factor <- d.my - (my.factor*3) 
# Generate data 
out <- as.data.frame(mvrnorm(1000, mu = c(0,0), 
          Sigma = matrix(c(1,d.cor,d.cor,1), ncol = 2), 
          empirical = TRUE)) 
# Adjust so that values are positive and include factors to match desired means and ranges 
out$V1.s <- (out$V1 - min(out$V1))*mx.factor + addx.factor 
out$V2.s <- (out$V2 - min(out$V2))*my.factor + addy.factor 
# Create liniear model to calculate intercept and slope 
fit <- lm(out$V2.s ~ out$V1.s, data=out) 
coef(fit) 
# Plot scatterplot along with regression line 
ggplot(out, aes(x=V1.s, y=V2.s)) + geom_point() + coord_fixed() + geom_smooth(method='lm') 
# Produce summary table 
summary(out)