Применить функцию corr к матрице с использованием уровней фактора?

Я пытаюсь использовать функцию corr () для расчета взвешенных значений. Это работает так: первый аргумент должен быть матрицей с двумя столбцами, соответствующими двум переменным, корреляцию которых мы хотим вычислить, а второй - вектором весов, который будет применяться к каждой паре наблюдений.

Вот пример.

> head(d)
 Shade_tolerance htot
1            4.56 25.0
2            2.73 23.5
3            2.73 21.5
4            3.97 17.0
5            4.00 25.5
6            4.00 23.5

> head(poids)
[1] 5.200440e-07 5.200440e-07 1.445016e-06 1.445016e-06 1.445016e-06 1.445016e-06

> corr(d,poids)
[1] 0.1357279

Итак, я получил это и могу использовать его в своей матрице, но я хотел бы вычислить различные корреляции в соответствии с уровнями фактора. Допустим, я использовал функцию tapply ().

> head(d2)
  Shade_tolerance htot idp
1            4.56 25.0  19
2            2.73 23.5  19
3            2.73 21.5  19
4            3.97 17.0  18
5            4.00 25.5  18
6            4.00 23.5  18

Поэтому моей мечтой было бы сделать что-то вроде этого:

tapply(as.matrix(d2[,c(1,2)]), d2$idp, corr)

За исключением того, что, как вы знаете, в tapply () первым элементом должен быть вектор, а не матрица.

У кого-нибудь есть решение для меня?

Спасибо большое за вашу помощь.

РЕДАКТИРОВАТЬ: Я только что понял, что мне не хватает весов для взвешенной корреляции в той части кадра данных, которую я вам показал. Таким образом, у него будет несколько способов взять и матрицу, и веса в соответствии с уровнями фактора.

> head(df)
  Shade_tolerance htot idp        poids
1            4.56 25.0  19 5.200440e-07
2            2.73 23.5  19 5.200440e-07
3            2.73 21.5  19 1.445016e-06
4            3.97 17.0  19 1.445016e-06
5            4.00 25.5  19 1.445016e-06
6            4.00 23.5  19 1.445016e-06

Надеюсь, это понятно.


person Tom    schedule 13.03.2013    source источник


Ответы (3)


Если у вас "огромный" data.frame, то использование data.table может помочь:

require(data.table)
dt <- as.data.table(df)
setkey(dt, "idp")
dt[, list(corr = corr(cbind(Shade_tolerance, htot), poids)), by=idp]

#    idp      corr
# 1:  18 0.9743547
# 2:  19 0.8387363
person Arun    schedule 13.03.2013
comment
Я только что отредактировал свой вопрос. Мне не хватало одного элемента для вычисления взвешенных корреляций. df $ poids, которые являются весами, должны где-то приниматься во внимание. - person Tom; 13.03.2013
comment
@Tom, если у вас огромные данные, попробуйте решение data.table в редактировании. - person Arun; 13.03.2013
comment
это будет быстрее, чем решение ddply? Тогда я попробую. Спасибо. - person Tom; 13.03.2013
comment
@Tom, да, конечно. Если у вас слишком много значений для idp, вы увидите разницу. С data.table ваше узкое место - это почти просто функция corr. - person Arun; 13.03.2013
comment
У меня более 44 000 значений idp. Я проверю ваше решение и дам вам знать. - person Tom; 13.03.2013
comment
Идеально. Это сработало, и это было очень быстро. Большое спасибо. И никаких проблем с NA, он просто дал мне NA для этих значений idp. - person Tom; 13.03.2013

Вот решение, использующее функцию ddply() из библиотеки plyr.

ddply(df,.(idp),
   summarise,kor=corr(cbind(Shade_tolerance, htot),poids))
  idp       kor
1  18 0.9743547
2  19 0.8387363
person Didzis Elferts    schedule 13.03.2013
comment
Я взял решения ddply только потому, что уже использовал их на огромном df, который у меня есть, но не мог найти, как это понять. Он работает (огромный df), я дам вам знать через несколько минут, если он сработал. Единственное, что меня немного беспокоит, это то, что у меня есть NA в моем df для некоторых значений как Shade capacity, так и htot, и я не думаю, что corr () может справиться с NA. - person Tom; 13.03.2013
comment
@Tom Я обновил свое решение - заменил as.matrix () на cbind (), потому что as.matrix () давал странные результаты. - person Didzis Elferts; 13.03.2013
comment
Ok. Что вы думаете о проблеме НП? - person Tom; 13.03.2013

Используя by и cbind,

 library(boot)
 by(dat,dat$idp,FUN=function(x)corr(cbind(x$Shade_tolerance,x$htot),x$poids))
dat$idp: 18
[1] 0.9743547
--------------------------------------------------------------------------------------- 
dat$idp: 19
[1] 0.7474093
person agstudy    schedule 13.03.2013
comment
Странно, я тоже дал by решение, но в моих откатах оно не появляется. - person Arun; 13.03.2013