R: hitung korelasi berdasarkan kelompok

17

Dalam R, saya memiliki kerangka data yang terdiri dari label kelas C (faktor) dan dua pengukuran, M1 dan M2 . Bagaimana cara menghitung korelasi antara M1 dan M2 dalam setiap kelas?

Idealnya, saya akan mendapatkan kembali kerangka data dengan satu baris untuk setiap kelas dan dua kolom: label kelas C dan korelasinya.

NPE
sumber

Jawaban:

20

Plyr paket adalah cara untuk pergi.

Ini adalah solusi sederhana:

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)

Outputnya adalah:

  group         COR
1     1  0.05152923
2     2 -0.15066838
3     3 -0.04717481
4     4  0.07899114
Tal Galili
sumber
1
(+1) plyrPaket yang bagus , bukan? :)
chl
Ini sangat bagus. Terima kasih telah menunjukkan paket plyr! Bisakah Anda jelaskan sintaks ". (Grup)"?
NPE
2
aix - tentu. Ini berarti "pisahkan data dengan variabel antara. (), Dan pada setiap bagian lakukan fungsi". Untuk memasukkan lebih banyak variabel, Anda cukup menggunakan sintaks ini:. (Var1, var2, var3). Yang seperti memotong data Anda dengan setiap kombinasi level var1, var2 dan var3. Dan pada setiap potongan untuk melakukan fungsi Anda. Paket ini dikelola oleh Hadley (juga penulis ggplot2), jadi saya percaya ini akan terus berkembang.
Tal Galili
2
Oh, dan BTW, Anda juga bisa menggunakan plyr dengan komputasi paralel pada beberapa core (hampir secara otomatis), lihat: r-statistics.com/2010/09/…
Tal Galili
1
Itu jawaban yang bagus, tapi saya heran tidak ada solusi
bawaan
12

Jika Anda cenderung menggunakan fungsi-fungsi dalam paket dasar, Anda dapat menggunakan byfungsi tersebut, lalu menyusun kembali data:

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)
hgcrpd
sumber
1
Terima kasih banyak! Saya sudah bereksperimen by, tetapi tidak tahu cara mengubah hasilnya menjadi bingkai data.
NPE
9

Contoh lain menggunakan paket dasar dan data contoh Tal:

DataCov <- do.call( rbind, lapply( split(xx, xx$group),
             function(x) data.frame(group=x$group[1], mCov=cov(x$a, x$b)) ) )
Joshua Ulrich
sumber
Solusi elegan Joshue. Apakah Anda pikir ada kasus di mana satu solusi lebih baik daripada yang lain?
Tal Galili
2
Saya pikir ini masalah preferensi. Contoh saya pada dasarnya adalah apa yang plyrdilakukan tetapi memberi Anda kontrol yang lebih baik, meskipun hampir tidak bersih. Pendapat saya akan berubah jika satu solusi memiliki profil waktu / memori yang lebih baik. Saya belum membandingkannya.
Joshua Ulrich
Bagaimana ini mengembalikan korelasinya?
2

Menggunakan data.table lebih pendek dari dplyr

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

Berikut adalah metode serupa yang akan memberi Anda tabel dengan nilai n dan p untuk setiap korelasi juga (dibulatkan menjadi 3 tempat desimal untuk kenyamanan):

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))))
}
AnnaCM
sumber
0

Berikut solusi yang lebih modern, menggunakan dplyr paket (yang belum ada saat pertanyaan diajukan):

Bangun input:

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

Hitung korelasinya:

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

Hasil:

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
Ken Williams
sumber