Відповіді:
Пакет 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
пакет, чи не так? :)