Odpowiedzi:
Pakiet plyr jest najlepszym rozwiązaniem.
Oto proste rozwiązanie:
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)
Dane wyjściowe będą:
group COR
1 1 0.05152923
2 2 -0.15066838
3 3 -0.04717481
4 4 0.07899114
Jeśli masz skłonność do korzystania z funkcji w pakiecie podstawowym, możesz użyć by
funkcji, a następnie ponownie złożyć dane:
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
, ale nie mogłem wymyślić, jak przekształcić wynik w ramkę danych.
Kolejny przykład z wykorzystaniem pakietów podstawowych i przykładowych danych Tala:
DataCov <- do.call( rbind, lapply( split(xx, xx$group),
function(x) data.frame(group=x$group[1], mCov=cov(x$a, x$b)) ) )
plyr
robi, ale daje lepszą kontrolę, choć nie jest tak czysty. Moja opinia zmieniłaby się, gdyby jedno rozwiązanie miało lepszy profil czas / pamięć. Nie porównałem ich jednak.
Oto podobna metoda, która da również tabelę z wartościami n i p dla każdej korelacji (dla wygody zaokrąglona do 3 miejsc po przecinku):
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))))
}
Oto bardziej nowoczesne rozwiązanie, wykorzystujące dplyr
pakiet (który jeszcze nie istniał, gdy zadano pytanie):
Skonstruuj dane wejściowe:
xx <- data.frame(group = rep(1:4, 100), a = rnorm(400) , b = rnorm(400) )
Oblicz korelacje:
library(dplyr)
xx %>%
group_by(group) %>%
summarize(COR=cor(a,b))
Wyjście:
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
paczka, prawda? :)