Как я могу сделать множественную корреляцию? - PullRequest
0 голосов
/ 10 февраля 2019

Мои данные состоят из 59 переменных (столбцы) и 500 наблюдений (каждый участник).Я должен сделать корреляцию одного элемента (столбца) с остальными элементами (все остальные столбцы).

Я сделал это для первого столбца другим, но я хотел бы повторить операцию вдля цикла.

Я пытался:

sapply(mydata[-1],function(y)cor.test(mydata$First_Item,y)$p.value)

Но если бы я сделал это для 2-го столбца 1-го столбца и для других 3:59, это не сработает.

Я хотел бы такую ​​вещь:

for (i in 1:59){
    sapply(mydata[,i],function(y)cor.test(mydata[,i],y)$p.value)
}

Большое спасибо!

РЕДАКТИРОВАТЬ:

B1_TP_CO_9999_01 = c(1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1) 
B1_TP_CO_9999_02 = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
B1_TP_CO_9999_03 = c(2, 0, 0, 2, 2, 2, 2, 2, 0, 1, 0, 2, 2, 2, 0) 
B1_TP_CO_9999_04 = c(0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0) 
B1_TP_CO_9999_05 = c(0, 2, 2, 2, 0, 0, 2, 2, 0, 0.5, 0, 0, 2, 1, 0)

Ответы [ 2 ]

0 голосов
/ 10 февраля 2019

Мы могли бы использовать expand.grid(), чтобы избежать вложенных циклов.

n <- ncol(mydata)
ex <- t(expand.grid(1:n, 1:n))                         # transpose with `t()`

myCor <- function(x) cor.test(x[, 1], x[, 2])$p.value  # test fun

Теперь мы запускаем один sapply() и упаковываем результат в матрицу с правильными именами.

MX <- matrix(sapply(seq(ncol(ex)), function(i) myCor(mydata[ex[, i]])), 
             ncol=n, dimnames=rep(list(names(mydata)), 2))

Выход:

MX <- round(MX, 3)
> MX
                 B1_TP_CO_9999_01 B1_TP_CO_9999_02 B1_TP_CO_9999_03 B1_TP_CO_9999_04 B1_TP_CO_9999_05
B1_TP_CO_9999_01            0.000               NA            0.043            1.000            0.757
B1_TP_CO_9999_02               NA               NA               NA               NA               NA
B1_TP_CO_9999_03            0.043               NA            0.000            0.857            0.703
B1_TP_CO_9999_04            1.000               NA            0.857            0.000            0.164
B1_TP_CO_9999_05            0.757               NA            0.703            0.164            0.000

Тест показывает нам, что это работает:

> cor.test(mydata[, 1], mydata[, 3])$p.value
[1] 0.04325627
> cor.test(mydata[, 4], mydata[, 3])$p.value
[1] 0.8574056
> cor.test(mydata[, 4], mydata[, 5])$p.value
[1] 0.164388

Если мы хотим избавиться от верхнеготреугольник, который мы наконец могли бы сделать

MX[upper.tri(MX, diag=TRUE)] <- ""

, что приведет к:

> as.data.frame(MX)[-n]
                 B1_TP_CO_9999_01 B1_TP_CO_9999_02 B1_TP_CO_9999_03 B1_TP_CO_9999_04
B1_TP_CO_9999_01                                                                    
B1_TP_CO_9999_02             <NA>                                                   
B1_TP_CO_9999_03            0.043             <NA>                                  
B1_TP_CO_9999_04                1             <NA>            0.857                 
B1_TP_CO_9999_05            0.757             <NA>            0.703            0.164

Примечание: Предупреждения основаны на ваших данных, вы можете альтернативно проверить код, например, с помощью mydata <- iris[-5].

Данные

mydata <- structure(list(B1_TP_CO_9999_01 = c(1, 0, 0, 0, 0, 1, 1, 1, 0, 
1, 0, 1, 1, 1, 1), B1_TP_CO_9999_02 = c(1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1), B1_TP_CO_9999_03 = c(2, 0, 0, 2, 2, 
2, 2, 2, 0, 1, 0, 2, 2, 2, 0), B1_TP_CO_9999_04 = c(0, 1, 1, 
0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0), B1_TP_CO_9999_05 = c(0, 
2, 2, 2, 0, 0, 2, 2, 0, 0.5, 0, 0, 2, 1, 0)), class = "data.frame", row.names = c(NA, 
-15L))
0 голосов
/ 10 февраля 2019

Функция ?cor создаст корреляционную матрицу красиво и быстро.Но если вам нужна пользовательская функция, например, чтобы упростить значение p, просто попробуйте двойной цикл.Не самый быстрый, но очень простой.

mydata <- matrix(runif(200),20,10)
p <- ncol(mydata)

cor_pval <- function(x, y) cor.test(x, y)$p.value
m <- matrix(0, p, p)

for (i in 1:ncol(mydata)) {
  for (j in 1:ncol(mydata)) {
    m[i,j] = cor_pval(mydata[,i], mydata[,j])
  }
}

Это довольно грубая сила.Вам не нужна функция, если вы не хотите, но она позволяет легко изменить метрику.Также вместо того, чтобы выполнять каждый столбец во втором цикле, вы можете начать j с i+1, чтобы не дублировать вычисления.Но, это должно получить ваш результат, и вы можете настраиваться оттуда, когда вы выясняете циклы.

Также здесь это с функцией apply, как вы делали.Если вы собираетесь построить результаты обратно в матрицу, вам нужно вставить 0 в ячейку для расположения вектора i=j из цикла for.

m2 <- matrix(0, p, p)
for (i in 1:p) {
 m2[i, ] = append(apply(mydata[,-i], 2, cor_pval, y = mydata[,i]), 0, after = i - 1)
}

all.equal(m, m2)
[1] TRUE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...