Створити випадкову змінну з визначеною кореляцією до існуючої змінної


71

Для дослідження моделювання я повинен генерувати випадкові змінні , які показують prefined (населення) кореляцію з існуючою Y .

Я подивився в Rпакети copulaі CDVineякі можуть виробляти випадкові багатовимірні розподілу із заданою структурою залежностей. Однак неможливо зафіксувати одну із отриманих змінних до існуючої змінної.

Будь-які ідеї та посилання на існуючі функції високо оцінені!


Висновок: з’явились дві обґрунтовані відповіді з різними рішеннями:

  1. R Сценарій по каракал, який обчислює випадкову змінну з точним (зразок) кореляції з визначеною змінною
  2. R Функція я опинилася, який обчислює випадкову величину з певною популяцією кореляцією з визначеним змінним

[@ttnphns ": я взяв на себе можливість розширити назву питання з одного фіксованого випадку змінної до довільної кількості фіксованих змінних; тобто як генерувати змінну, що має попередньо визначені корекції з деякими фіксованими, існуючими змінними.]


2
Дивіться це пов’язане питання stats.stackexchange.com/questions/13382/…, яке безпосередньо стосується вашого питання (принаймні теоретичної сторони його).
Макрос

Наступний Q також сильно пов'язаний і буде представляти інтерес: Як генерувати корельовані випадкові числа (задані відхилення та ступінь кореляції) .
gung

Відповіді:


56

Ось ще один: для векторів із середнім 0 їх співвідношення дорівнює косинусу їхнього кута. Отже, один із способів знайти вектор з точно потрібною кореляцією r , що відповідає куту θ :xrθ

  1. отримати фіксований вектор і випадковий вектор x 2x1x2
  2. центрують обидва вектора (середнє 0), даючи вектори , ˙ x 2x˙1x˙2
  3. зробіть ортогональним до ˙ x 1 (проекція на ортогональний підпростір), даючи ˙ x 2x˙2x˙1x˙2
  4. масштаб і до довжини 1, даючи іx˙1ˉ x 1 ˉ x 2x˙2x¯1x¯2
  5. ˉ x 1θ ˉ x 1rx1x¯2+(1/tan(θ))x¯1 - вектор, кут на є , і кореляція з при цьому дорівнює . Це також кореляція з оскільки лінійні перетворення залишають кореляцію незмінною.x¯1θx¯1rx1

Ось код:

n     <- 20                    # length of vector
rho   <- 0.6                   # desired correlation = cos(angle)
theta <- acos(rho)             # corresponding angle
x1    <- rnorm(n, 1, 1)        # fixed given data
x2    <- rnorm(n, 2, 0.5)      # new random data
X     <- cbind(x1, x2)         # matrix
Xctr  <- scale(X, center=TRUE, scale=FALSE)   # centered columns (mean 0)

Id   <- diag(n)                               # identity matrix
Q    <- qr.Q(qr(Xctr[ , 1, drop=FALSE]))      # QR-decomposition, just matrix Q
P    <- tcrossprod(Q)          # = Q Q'       # projection onto space defined by x1
x2o  <- (Id-P) %*% Xctr[ , 2]                 # x2ctr made orthogonal to x1ctr
Xc2  <- cbind(Xctr[ , 1], x2o)                # bind to matrix
Y    <- Xc2 %*% diag(1/sqrt(colSums(Xc2^2)))  # scale columns to length 1

x <- Y[ , 2] + (1 / tan(theta)) * Y[ , 1]     # final new vector
cor(x1, x)                                    # check correlation = rho

введіть тут опис зображення

Для ортогональної проекції я використав -розклад для поліпшення чисельної стійкості, оскільки тоді просто .Q R P = Q Q PQRP=QQ


Я намагався переписати код у синтаксис SPSS. Я натрапляю на ваш QR-розклад, який повертає 20x1 стовпець. У SPSS у мене є ортонормалізація за Грамом-Шмідтом (що також є розкладом QR), але не в змозі повторити ваш результуючий стовпець Q. Чи можете ви жувати свою QR-дію, будь ласка. Або вкажіть деякий обхід, щоб отримати проекцію. Дякую.
ttnphns

@caracal, P <- X %*% solve(t(X) %*% X) %*% t(X)не дає r = 0,6, тому це не вирішується . Я все ще розгублений. (Буду радий наслідувати ваше вираження Q <- qr.Q(qr(Xctr[ , 1, drop=FALSE]))в SPSS, але не знаю як.)
ttnphns

@ttnphns Вибачте за плутанину, мій коментар був для загального випадку. Застосування його до ситуації на прикладі: Отримати матрицю проекції за допомогою QR-розкладання якраз для стабільності числення. Ви можете отримати матрицю проекції як , якщо підпростір , натягнуте на стовпці матриці . В R ви можете тут писати, оскільки підпростір охоплюється першим стовпцем . Тоді матриця проекції на ортогональний доповнення є IP. XP=X(XX)1XXXctr[ , 1] %*% solve(t(Xctr[ , 1]) %*% Xctr[ , 1]) %*% t(Xctr[ , 1])Xctr
каракал

4
Чи може хтось уточнити, як виконати щось подібне для більш ніж двох зразків? Скажіть, якщо я хотів 3 зразки, які корелюються попарно по rho, як я можу перетворити це рішення для досягнення цього?
Андре Терра

для лімітного випадку rho=1я вважаю корисним зробити щось подібне: if (isTRUE(all.equal(rho, 1))) rho <- 1-10*.Machine$double.epsінакше я отримував NaNs
PatrickT

19

Я опишу найбільш загальне можливе рішення. Вирішення проблеми в цій загальності дозволяє досягти надзвичайно компактної реалізації програмного забезпечення: достатньо двох коротких рядків Rкоду.

Виберіть вектор такої ж довжини, як , відповідно до будь-якого вподобання. Нехай бути залишки регресії найменших квадратів проти : це витягує компонент з . Додаючи тому відповідне кратне в , ми можемо виробляти вектор , який має будь-яку необхідну кореляційний з . До довільної постійної добавки та позитивної мультиплікативної константи - яку ви можете будь-яким способом вибрати - рішення полягає вY Y X Y Y X Y Y ρ YXYYXYYXYYρY

XY;ρ=ρSD(Y)Y+1ρ2SD(Y)Y.

(" " означає будь-який розрахунок, пропорційний стандартному відхиленню.)SD


Ось робочий Rкод. Якщо ви не постачаєте , код отримає його значення з багатофакторного стандартного розподілу Normal.X

complement <- function(y, rho, x) {
  if (missing(x)) x <- rnorm(length(y)) # Optional: supply a default if `x` is not given
  y.perp <- residuals(lm(x ~ y))
  rho * sd(y.perp) * y + y.perp * sd(y) * sqrt(1 - rho^2)
}

Y50XY;ρYX=(1,2,,50)Y

Малюнок

Серед сюжетів є надзвичайна схожість, чи не так :-).


Якщо ви хочете експериментувати, ось код, який створив ці дані та рисунок. (Я не намагався використовувати свободу для зміщення та масштабування результатів, що є простими операціями.)

y <- rnorm(50, sd=10)
x <- 1:50 # Optional
rho <- seq(0, 1, length.out=6) * rep(c(-1,1), 3)
X <- data.frame(z=as.vector(sapply(rho, function(rho) complement(y, rho, x))),
                rho=ordered(rep(signif(rho, 2), each=length(y))),
                y=rep(y, length(rho)))

library(ggplot2)
ggplot(X, aes(y,z, group=rho)) + 
  geom_smooth(method="lm", color="Black") + 
  geom_rug(sides="b") + 
  geom_point(aes(fill=rho), alpha=1/2, shape=21) +
  facet_wrap(~ rho, scales="free")

YXY1,Y2,,Yk;ρ1,ρ2,,ρkYiYiXYiYY

RYiy

y <- scale(y)             # Makes computations simpler
e <- residuals(lm(x ~ y)) # Take out the columns of matrix `y`
y.dual <- with(svd(y), (n-1)*u %*% diag(ifelse(d > 0, 1/d, 0)) %*% t(v))
sigma2 <- c((1 - rho %*% cov(y.dual) %*% rho) / var(e))
return(y.dual %*% rho + sqrt(sigma2)*e)

Далі йде більш повна реалізація для тих, хто хотів би експериментувати.

complement <- function(y, rho, x) {
  #
  # Process the arguments.
  #
  if(!is.matrix(y)) y <- matrix(y, ncol=1)
  if (missing(x)) x <- rnorm(n)
  d <- ncol(y)
  n <- nrow(y)
  y <- scale(y) # Makes computations simpler
  #
  # Remove the effects of `y` on `x`.
  #
  e <- residuals(lm(x ~ y))
  #
  # Calculate the coefficient `sigma` of `e` so that the correlation of
  # `y` with the linear combination y.dual %*% rho + sigma*e is the desired
  # vector.
  #
  y.dual <- with(svd(y), (n-1)*u %*% diag(ifelse(d > 0, 1/d, 0)) %*% t(v))
  sigma2 <- c((1 - rho %*% cov(y.dual) %*% rho) / var(e))
  #
  # Return this linear combination.
  #
  if (sigma2 >= 0) {
    sigma <- sqrt(sigma2) 
    z <- y.dual %*% rho + sigma*e
  } else {
    warning("Correlations are impossible.")
    z <- rep(0, n)
  }
  return(z)
}
#
# Set up the problem.
#
d <- 3           # Number of given variables
n <- 50          # Dimension of all vectors
x <- 1:n         # Optionally: specify `x` or draw from any distribution
y <- matrix(rnorm(d*n), ncol=d) # Create `d` original variables in any way
rho <- c(0.5, -0.5, 0)          # Specify the correlations
#
# Verify the results.
#
z <- complement(y, rho, x)
cbind('Actual correlations' = cor(cbind(z, y))[1,-1],
      'Target correlations' = rho)
#
# Display them.
#
colnames(y) <- paste0("y.", 1:d)
colnames(z) <- "z"
pairs(cbind(z, y))

YBTW, this method readily generalizes to more... Just use ordinary least squares... and form a suitable linear combination

1
@ttnphns Я це зробив.
whuber

1
Дуже дякую! Я бачу, і я сьогодні зашифрував ваш підхід у SPSS. Дійсно чудова ваша пропозиція. Я ніколи не думав про поняття подвійної основи як застосовне для вирішення завдання.
ttnphns

Чи можна застосувати подібний підхід, щоб створити рівномірно розподілений вектор? Тобто, у мене є існуючий вектор xі хочу генерувати новий вектор, yспіввіднесений, xале також хочу, щоб yвектор був рівномірно розподілений.
Skumin

@Skumin Подумайте про використання копули для цього, щоб ви могли контролювати зв’язок між двома векторами.
whuber

6

Ось ще один обчислювальний підхід (рішення адаптоване з допису на форумі Енріко Шумана). На думку Вольфганга (див. Коментарі), це обчислювально ідентично рішення, запропонованому ttnphns.

ρρ

ρx

# returns a data frame of two variables which correlate with a population correlation of rho
# If desired, one of both variables can be fixed to an existing variable by specifying x
getBiCop <- function(n, rho, mar.fun=rnorm, x = NULL, ...) {
     if (!is.null(x)) {X1 <- x} else {X1 <- mar.fun(n, ...)}
     if (!is.null(x) & length(x) != n) warning("Variable x does not have the same length as n!")

     C <- matrix(rho, nrow = 2, ncol = 2)
     diag(C) <- 1

     C <- chol(C)

     X2 <- mar.fun(n)
     X <- cbind(X1,X2)

     # induce correlation (does not change X1)
     df <- X %*% C

     ## if desired: check results
     #all.equal(X1,X[,1])
     #cor(X)

     return(df)
}

Функція також може використовувати ненормальні граничні розподіли, регулюючи параметр mar.fun. Однак слід зазначити, що фіксація однієї змінної тільки , здається, працює з нормально розподіленої змінної x! (що може стосуватися коментаря Макроса).

Також зауважте, що "малий поправочний коефіцієнт" з початкової публікації було видалено, оскільки, здається, упереджують отримані кореляції, принаймні, у випадку розподілу Гаусса та Пірсона (також див. Коментарі).


ρ

1
Неважко показати, що, за винятком тієї "невеликої корекції rho" (мета якої у цьому контексті мені ухиляється ), це точно те саме, що запропоновано раніше ttnphns. Метод просто заснований на розкладі Холеського кореляційної матриці для отримання бажаної матриці перетворення. Див, наприклад: en.wikipedia.org/wiki / ... . І так, це дасть вам лише два вектори, чиє співвідношення населення дорівнює rho.
Вольфганг

"Невелике виправлення до rho" було в початковій публікації і описане тут . Насправді я насправді цього не розумію; але дослідження 50000 модельованих кореляцій з rho = .3 показує, що без "малої корекції" в середньому виробляється значення r .299, тоді як при корекції в середньому .312 (що є значенням виправленого rho) виробляється. Тому я вилучив цю частину з функції.
Фелікс S

Я знаю, що це давнє, але я також хочу зазначити, що цей метод не працюватиме для непозитивних визначених кореляційних матриць. Напр. - співвідношення -1.
zzk

1
Дякую; Я помітив , що якщо x1 не нормується середнє значення = 0, С.О. = 1, і ви не хочете плавно змінювати масштаб його, вам потрібно змінити рядок: X2 <- mar.fun(n)щоб X2 <- mar.fun(n,mean(x),sd(x))отримати бажане співвідношення між x1 та x2
Dave M

6

XYXrXrY=rX+EE0sd=1r2XYrXYXρ=r

rEXEXYX1,X2,X3,...

XrYYrY


Оновлення 11 листопада 2017 року. Я сьогодні натрапив на цю стару тему і вирішив розширити свою відповідь, показавши алгоритм ітеративної підгонки, про яку я говорив спочатку.

Y X

Застереження: Це ітераційне рішення, яке я знайшов поступається відмінному, засноване на пошуку подвійної основи та запропонованому сьогодні @whuber у цій темі. @ рішення Whuber не є ітераційним, і, що ще важливіше, для мене, здається, це впливає на значення вхідної змінної "pig" трохи менше, ніж на "мій" алгоритм (це було б перевагою, якщо завдання - "виправити" існуюча змінна і не створювати випадкових змінних з нуля). Я все-таки публікую шахту з цікавості і тому, що вона працює (див. Також виноску).

X1,X2,...,XmYYr1,r2,...,rmX

YXYY

  1. rdf=n1Sj=rjdfjX

  2. dfYXdf

  3. YXrb=(XX)1S

  4. YY^=Xb

  5. E=YY^

  6. SSS=dfSSY^

  7. EXjCj=i=1nEiXij

  8. EC0i

    Ei[corrected]=Eij=1mCjXijnj=1mXij2

    (знаменник не змінюється на ітераціях, обчисли його заздалегідь)

    E0 EC

    Ei[corrected]=Eij=1mCjXij3i=1nXij2j=1mXij2

    1

  9. SSEEi[corrected]=EiSSS/SSE

    mrSSSn

  10. CErYY[corrected]=Y^+E

  11. Y

  12. Yr

YrY


1YX


1
Дякую за вашу відповідь. Це емпіричне / ітеративне рішення, про яке я думав. Однак для мого моделювання мені потрібно більш аналітичне рішення без дорогої процедури підгонки. На щастя, я просто знайшов рішення, яке незабаром опублікую ...
Felix S

Це працює для генерації біваріантних нормалей, але не працює для довільного розподілу (або будь-якого непридатного) розподілу
Макрос

1
Я не бачу, чому ви пропонуєте ітерацію, коли ви можете виготовити весь конус розчинів безпосередньо. Чи є якась особлива мета цього підходу?
whuber

1
Y

1
@whuber, ваш коментар - це те, чого я чекав; насправді моя відповідь (про гетеросцедастичність, з якою я посилаюсь) мала для вас виклик: можливо, це запрошення опублікувати ваше рішення - таке ретельне та геніальне, як ви зазвичай робите.
ttnphns

4

Мені здавалося, що я займаюся деяким програмуванням, тому я взяв видалену відповідь @ Адама і вирішив написати приємну реалізацію в Р. Я зосередився на використанні функціонально орієнтованого стилю (тобто циклічного циклічного циклу). Загальна ідея полягає в тому, щоб взяти два вектори, довільно переставляючи один з векторів, поки між ними не буде досягнуто певної кореляції. Такий підхід дуже жорстокий, але простий у здійсненні.

Спочатку ми створюємо функцію, яка випадковим чином перетворює вхідний вектор:

randomly_permute = function(vec) vec[sample.int(length(vec))]
randomly_permute(1:100)
  [1]  71  34   8  98   3  86  28  37   5  47  88  35  43 100  68  58  67  82
 [19]  13   9  61  10  94  29  81  63  14  48  76   6  78  91  74  69  18  12
 [37]   1  97  49  66  44  40  65  59  31  54  90  36  41  93  24  11  77  85
 [55]  32  79  84  15  89  45  53  22  17  16  92  55  83  42  96  72  21  95
 [73]  33  20  87  60  38   7   4  52  27   2  80  99  26  70  50  75  57  19
 [91]  73  62  23  25  64  51  30  46  56  39

... і створити деякі приклади даних

vec1 = runif(100)
vec2 = runif(100)

... записати функцію, яка перестановлює вхідний вектор, і співвідносить його з опорним вектором:

permute_and_correlate = function(vec, reference_vec) {
    perm_vec = randomly_permute(vec)
    cor_value = cor(perm_vec, reference_vec)
    return(list(vec = perm_vec, cor = cor_value))
  }
permute_and_correlate(vec2, vec1)
$vec
  [1] 0.79072381 0.23440845 0.35554970 0.95114398 0.77785348 0.74418811
  [7] 0.47871491 0.55981826 0.08801319 0.35698405 0.52140366 0.73996913
 [13] 0.67369873 0.85240338 0.57461506 0.14830718 0.40796732 0.67532970
 [19] 0.71901990 0.52031017 0.41357545 0.91780357 0.82437619 0.89799621
 [25] 0.07077250 0.12056045 0.46456652 0.21050067 0.30868672 0.55623242
 [31] 0.84776853 0.57217746 0.08626022 0.71740151 0.87959539 0.82931652
 [37] 0.93903143 0.74439384 0.25931398 0.99006038 0.08939812 0.69356590
 [43] 0.29254936 0.02674156 0.77182339 0.30047034 0.91790830 0.45862163
 [49] 0.27077191 0.74445997 0.34622648 0.58727094 0.92285322 0.83244284
 [55] 0.61397396 0.40616274 0.32203732 0.84003379 0.81109473 0.50573325
 [61] 0.86719899 0.45393971 0.19701975 0.63877904 0.11796154 0.26986325
 [67] 0.01581969 0.52571331 0.27087693 0.33821824 0.52590383 0.11261002
 [73] 0.89840404 0.82685046 0.83349287 0.46724807 0.15345334 0.60854785
 [79] 0.78854984 0.95770015 0.89193212 0.18885955 0.34303707 0.87332019
 [85] 0.08890968 0.22376395 0.02641979 0.43377516 0.58667068 0.22736077
 [91] 0.75948043 0.49734797 0.25235660 0.40125309 0.72147500 0.92423638
 [97] 0.27980561 0.71627101 0.07729027 0.05244047

$cor
[1] 0.1037542

... і повторіть тисячу разів:

n_iterations = lapply(1:1000, function(x) permute_and_correlate(vec2, vec1))

Зверніть увагу , що правила області Лепеха гарантувати , що vec1і vec2знаходяться в глобальному середовищі, поза анонімної функції , використовуваної вище. Отже, перестановки відносно оригінальних наборів даних тесту, які ми створили.

Далі ми знаходимо максимальну кореляцію:

cor_values = sapply(n_iterations, '[[', 'cor')
n_iterations[[which.max(cor_values)]]
$vec
  [1] 0.89799621 0.67532970 0.46456652 0.75948043 0.30868672 0.83244284
  [7] 0.86719899 0.55623242 0.63877904 0.73996913 0.71901990 0.85240338
 [13] 0.81109473 0.52571331 0.82931652 0.60854785 0.19701975 0.26986325
 [19] 0.58667068 0.52140366 0.40796732 0.22736077 0.74445997 0.40125309
 [25] 0.89193212 0.52031017 0.92285322 0.91790830 0.91780357 0.49734797
 [31] 0.07729027 0.11796154 0.69356590 0.95770015 0.74418811 0.43377516
 [37] 0.55981826 0.93903143 0.30047034 0.84776853 0.32203732 0.25235660
 [43] 0.79072381 0.58727094 0.99006038 0.01581969 0.41357545 0.52590383
 [49] 0.27980561 0.50573325 0.92423638 0.11261002 0.89840404 0.15345334
 [55] 0.61397396 0.27077191 0.12056045 0.45862163 0.18885955 0.77785348
 [61] 0.23440845 0.05244047 0.25931398 0.57217746 0.35554970 0.34622648
 [67] 0.21050067 0.08890968 0.84003379 0.95114398 0.83349287 0.82437619
 [73] 0.46724807 0.02641979 0.71740151 0.74439384 0.14830718 0.82685046
 [79] 0.33821824 0.71627101 0.77182339 0.72147500 0.08801319 0.08626022
 [85] 0.87332019 0.34303707 0.45393971 0.47871491 0.29254936 0.08939812
 [91] 0.35698405 0.67369873 0.27087693 0.78854984 0.87959539 0.22376395
 [97] 0.02674156 0.07077250 0.57461506 0.40616274

$cor
[1] 0.3166681

... або знайти найближче значення до співвідношення 0,2:

n_iterations[[which.min(abs(cor_values - 0.2))]]
$vec
  [1] 0.02641979 0.49734797 0.32203732 0.95770015 0.82931652 0.52571331
  [7] 0.25931398 0.30047034 0.55981826 0.08801319 0.29254936 0.23440845
 [13] 0.12056045 0.89799621 0.57461506 0.99006038 0.27077191 0.08626022
 [19] 0.14830718 0.45393971 0.22376395 0.89840404 0.08890968 0.15345334
 [25] 0.87332019 0.92285322 0.50573325 0.40796732 0.91780357 0.57217746
 [31] 0.52590383 0.84003379 0.52031017 0.67532970 0.83244284 0.95114398
 [37] 0.81109473 0.35554970 0.92423638 0.83349287 0.34622648 0.18885955
 [43] 0.61397396 0.89193212 0.74445997 0.46724807 0.72147500 0.33821824
 [49] 0.71740151 0.75948043 0.52140366 0.69356590 0.41357545 0.21050067
 [55] 0.87959539 0.11796154 0.73996913 0.30868672 0.47871491 0.63877904
 [61] 0.22736077 0.40125309 0.02674156 0.26986325 0.43377516 0.07077250
 [67] 0.79072381 0.08939812 0.86719899 0.55623242 0.60854785 0.71627101
 [73] 0.40616274 0.35698405 0.67369873 0.82437619 0.27980561 0.77182339
 [79] 0.19701975 0.82685046 0.74418811 0.58667068 0.93903143 0.74439384
 [85] 0.46456652 0.85240338 0.34303707 0.45862163 0.91790830 0.84776853
 [91] 0.78854984 0.05244047 0.58727094 0.77785348 0.01581969 0.27087693
 [97] 0.07729027 0.71901990 0.25235660 0.11261002

$cor
[1] 0.2000199

Щоб отримати більш високу кореляцію, потрібно збільшити кількість ітерацій.


2

Y1Y2,,YnR

Рішення:

  1. CCT=R
  2. X2,,XnY1
  3. Y1
  4. Y=CXYiY1

Код Python:

import numpy as np
import math
from scipy.linalg import toeplitz, cholesky
from statsmodels.stats.moment_helpers import cov2corr

# create the large correlation matrix R
p = 4
h = 2/p
v = np.linspace(1,-1+h,p)
R = cov2corr(toeplitz(v))

# create the first variable
T = 1000;
y = np.random.randn(T)

# generate p-1 correlated randoms
X = np.random.randn(T,p)
X[:,0] = y
C = cholesky(R)
Y = np.matmul(X,C)

# check that Y didn't change
print(np.max(np.abs(Y[:,0]-y)))

# check the correlation matrix
print(R)
print(np.corrcoef(np.transpose(Y)))

Тестовий вихід:

0.0
[[ 1.   0.5  0.  -0.5]
 [ 0.5  1.   0.5  0. ]
 [ 0.   0.5  1.   0.5]
 [-0.5  0.   0.5  1. ]]
[[ 1.          0.50261766  0.02553882 -0.46259665]
 [ 0.50261766  1.          0.51162821  0.05748082]
 [ 0.02553882  0.51162821  1.          0.51403266]
 [-0.46259665  0.05748082  0.51403266  1.        ]]

Y1

@whuber це була помилка
Аксакал

0

Створіть нормальні змінні за допомогою матриці коваріації ВІДОМЛЕННЯ, як дано

covsam <- function(nobs,covm, seed=1237) {; 
          library (expm);
          # nons=number of observations, covm = given covariance matrix ; 
          nvar <- ncol(covm); 
          tot <- nvar*nobs;
          dat <- matrix(rnorm(tot), ncol=nvar); 
          covmat <- cov(dat); 
          a2 <- sqrtm(solve(covmat)); 
          m2 <- sqrtm(covm);
          dat2 <- dat %*% a2 %*% m2 ; 
          rc <- cov(dat2);};
          cm <- matrix(c(1,0.5,0.1,0.5,1,0.5,0.1,0.5,1),ncol=3);
          cm; 
          res <- covsam(10,cm)  ;
          res;

Створіть нормальні змінні за допомогою матриці коваріації ПОПУЛЯЦІЇ, як дано

covpop <- function(nobs,covm, seed=1237) {; 
          library (expm); 
          # nons=number of observations, covm = given covariance matrix;
          nvar <- ncol(covm); 
          tot <- nvar*nobs;  
          dat <- matrix(rnorm(tot), ncol=nvar); 
          m2 <- sqrtm(covm);
          dat2 <- dat %*% m2;  
          rc <- cov(dat2); }; 
          cm <- matrix(c(1,0.5,0.1,0.5,1,0.5,0.1,0.5,1),ncol=3);
          cm; 
          res <- covpop(10,cm); 
          res

2
Вам потрібно навчитися форматувати код у відповіді! Існує конкретна опція, щоб позначити текст як фрагменти коду, використовувати його!
kjetil b halvorsen

-6

Просто створіть випадковий вектор і сортуйте, поки не отримаєте потрібний r.


У яких ситуаціях це було б кращим перед вищезазначеними рішеннями?
Andy W

Ситуація, коли користувач хоче простої відповіді. Я читав подібне запитання на r форумі, і його відповідь була дана.
Адам

3
r

3
Якщо ця відповідь була надана на форумі r-help, я підозрюю, що це або (а) іронічно (тобто призначене як жарт), або (b) запропоноване тим, хто не дуже статистично складний. Якщо сказати це більш лаконічно, це погана відповідь на питання. -1
gung
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.