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.

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

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)

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

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]

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

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.