R: gruba göre korelasyonu hesapla


17

R de, bir sınıf etiketi C (bir faktör) ve iki ölçüm, M1 ve M2 içeren bir veri çerçevem ​​var . Her sınıfta M1 ve M2 arasındaki korelasyonu nasıl hesaplayabilirim ?

İdeal olarak, her sınıf için bir satır ve iki sütun içeren bir veri çerçevesini geri alacağım: sınıf etiketi C ve korelasyon.

Yanıtlar:


20

Paket plyr gitmek için bir yoldur.

İşte basit bir çözüm:

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)

Çıktı şöyle olacaktır:

  group         COR
1     1  0.05152923
2     2 -0.15066838
3     3 -0.04717481
4     4  0.07899114

1
(+1) Güzel plyrpaket, değil mi? :)
chl

Harika çalışıyor. Plyr paketini gösterdiğin için teşekkürler! ". (Grup)" sözdizimini açıklayabilir misiniz?
NPE

2
aix - tabii. "Verileri. () Arasında değişkene böl ve her alt kümede işlevi gerçekleştir" anlamına gelir. Daha fazla değişken içermesi için şu sözdizimini kullanmanız yeterlidir:. (Var1, var2, var3). Bu, var1, var2 ve var3 seviyelerinin her bir kombinasyonuyla verilerinizi kesmek gibidir. Ve her kesimde işlevinizi yerine getirmek için. Bu paket Hadley (ayrıca ggplot2'nin inci yazarı) tarafından korunmaktadır, bu yüzden gelişmeye devam edeceğine inanıyorum.
Tal Galili

2
Oh, ve BTW, birçok çekirdekte paralel bir bilgisayarla (neredeyse otomatik olarak) plyr de kullanabilirsiniz, bkz: r-statistics.com/2010/09/…
Tal Galili

1
Bu güzel bir cevap, ama bunun için yerleşik bir çözüm olmadığını şaşırdım, cor (x, y, by = z) gibi bir şey çok sezgisel olurdu ...
Waldir Leoncio

12

Temel paketteki işlevleri kullanmaya eğilimliyseniz, byişlevi kullanabilir ve ardından verileri yeniden birleştirebilirsiniz:

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)

1
Güzel, teşekkürler! Deniyordum by, ancak sonucu bir veri çerçevesine nasıl dönüştüreceğimizi anlayamadım.
NPE

9

Temel paketleri ve Tal'in örnek verilerini kullanan başka bir örnek:

DataCov <- do.call( rbind, lapply( split(xx, xx$group),
             function(x) data.frame(group=x$group[1], mCov=cov(x$a, x$b)) ) )

Zarif çözüm Joshue. Bir çözümün diğerinden daha iyi olduğu durumlar olduğunu düşünüyor musunuz?
Tal Galili

2
Bence bu bir tercih meselesi. Örneğim aslında ne plyrişe yarıyor ancak size daha iyi bir kontrol sağlıyor, ancak neredeyse temiz değil. Bir çözüm daha iyi bir zaman / bellek profiline sahip olsaydı fikrim değişecekti. Ama ben onları karşılaştırmadım.
Joshua Ulrich

Bu korelasyonu nasıl geri getirir?

2

Data.table kullanımı dplyr'den daha kısadır

dt <- data.table(xx)
dtCor <- dt[, .(mCor = cor(M1,M2)), by=C]

0

İşte size her korelasyon için n ve p değerlerini içeren bir tablo (benzerlik için 3 ondalık basamağa yuvarlanmış) veren benzer bir yöntem:

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))))
}

0

İşte dplyrpaketi kullanarak (soru sorulduğunda henüz mevcut olmayan) daha modern bir çözüm :

Girdiyi oluşturun:

xx <- data.frame(group = rep(1:4, 100), a = rnorm(400) , b = rnorm(400) )

Korelasyonları hesaplayın:

library(dplyr)
xx %>%
  group_by(group) %>%
  summarize(COR=cor(a,b))

Çıktı:

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.