Ответы:
Пакет plyr это путь.
Вот простое решение:
xx <- data.frame(group = rep(1:4, 100), a = rnorm(400) , b = rnorm(400) )
head(xx)
require(plyr)
func <- function(xx)
{
return(data.frame(COR = cor(xx$a, xx$b)))
}
ddply(xx, .(group), func)
Выход будет:
group COR
1 1 0.05152923
2 2 -0.15066838
3 3 -0.04717481
4 4 0.07899114
Если вы склонны использовать функции в базовом пакете, вы можете использовать by
функцию, а затем собрать данные:
xx <- data.frame(group = rep(1:4, 100), a = rnorm(400) , b = rnorm(400) )
head(xx)
# This returns a "by" object
result <- by(xx[,2:3], xx$group, function(x) {cor(x$a, x$b)})
# You get pretty close to what you want if you coerce it into a data frame via a matrix
result.dataframe <- as.data.frame(as.matrix(result))
# Add the group column from the row names
result.dataframe$C <- rownames(result)
by
, но не мог понять, как преобразовать результат в кадр данных.
Другой пример, использующий базовые пакеты и данные примера Тала:
DataCov <- do.call( rbind, lapply( split(xx, xx$group),
function(x) data.frame(group=x$group[1], mCov=cov(x$a, x$b)) ) )
plyr
делает, но он дает вам более точный контроль, хотя и не так чист. Мое мнение изменилось бы, если бы у одного решения был лучший профиль времени / памяти. Я не сравнивал их, хотя.
Вот аналогичный метод, который даст вам таблицу со значениями n и p для каждой корреляции (для удобства округлены до 3 десятичных знаков):
library(Hmisc)
corrByGroup <- function(xx){
return(data.frame(cbind(correl = round(rcorr(xx$a, xx$b)$r[1,2], digits=3),
n = rcorr(xx$a, xx$b)$n[1,2],
pvalue = round(rcorr(xx$a, xx$b)$P[1,2], digits=3))))
}
Вот более современное решение, использующее dplyr
пакета (которого еще не было, когда задавался вопрос):
Построить вход:
xx <- data.frame(group = rep(1:4, 100), a = rnorm(400) , b = rnorm(400) )
Вычислить соотношения:
library(dplyr)
xx %>%
group_by(group) %>%
summarize(COR=cor(a,b))
Выход:
Source: local data frame [4 x 2]
group COR
(int) (dbl)
1 1 0.05112400
2 2 0.14203033
3 3 -0.02334135
4 4 0.10626273
plyr
пакет, не так ли? :)