R: tính tương quan theo nhóm


17

Trong R, tôi có một khung dữ liệu bao gồm nhãn lớp C (một yếu tố) và hai phép đo, M1M2 . Làm cách nào để tính toán mối tương quan giữa M1M2 trong mỗi lớp?

Lý tưởng nhất là tôi lấy lại một khung dữ liệu với một hàng cho mỗi lớp và hai cột: nhãn lớp C và mối tương quan.

Câu trả lời:


20

Gói plyr là con đường để đi.

Đây là một giải pháp đơn giản:

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)

Đầu ra sẽ là:

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

1
(+1) plyrGói đẹp phải không? :)
chl

Điều này làm việc tuyệt vời. Cảm ơn đã chỉ ra gói plyr! Bạn có thể vui lòng giải thích cú pháp ". (Nhóm)" không?
NPE

2
aix - chắc chắn rồi Nó có nghĩa là "phân chia dữ liệu theo biến giữa. () Và trên mỗi tập hợp con thực hiện chức năng". Để có nó bao gồm nhiều biến hơn, bạn chỉ cần sử dụng cú pháp này :. (Var1, var2, var3). Điều này giống như cắt dữ liệu của bạn theo từng tổ hợp các cấp độ var1, var2 và var3. Và trên mỗi lần cắt để thực hiện chức năng của bạn. Gói này được duy trì bởi Hadley (cũng là tác giả của ggplot2), vì vậy tôi tin rằng nó sẽ tiếp tục phát triển.
Tal Galili

2
Ồ, và BTW, bạn cũng có thể sử dụng plyr với tính toán song song trên một số lõi (gần như tự động), xem: r-statistic.com/2010/09/ Thẻ
Tal Galili

1
Đó là một câu trả lời hay, nhưng tôi ngạc nhiên rằng không có giải pháp tích hợp nào cho việc này, một cái gì đó như cor (x, y, by = z) sẽ rất trực quan ...
Waldir Leoncio

12

Nếu bạn có xu hướng sử dụng các chức năng trong gói cơ sở, bạn có thể sử dụng bychức năng đó, sau đó lắp lại dữ liệu:

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
Rất vui, cảm ơn! Tôi đã thử nghiệm by, nhưng không thể tìm ra cách chuyển đổi kết quả thành khung dữ liệu.
NPE

9

Một ví dụ khác sử dụng các gói cơ sở và dữ liệu ví dụ của Tal:

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

Giải pháp thanh lịch Joshue. Bạn có nghĩ rằng có những trường hợp khi một giải pháp tốt hơn thì một giải pháp khác?
Tal Galili

2
Tôi nghĩ đó là vấn đề ưu tiên. Ví dụ của tôi về cơ bản là những gì plyrlàm nhưng nó mang lại cho bạn sự kiểm soát tốt hơn, mặc dù nó gần như không sạch sẽ. Ý kiến ​​của tôi sẽ thay đổi nếu một giải pháp có hồ sơ thời gian / bộ nhớ tốt hơn. Tôi đã không so sánh họ mặc dù.
Joshua Ulrich

Làm thế nào điều này trả lại mối tương quan?

2

Sử dụng data.table ngắn hơn dplyr

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

0

Đây là một phương pháp tương tự sẽ cung cấp cho bạn một bảng có các giá trị n và p cho mỗi tương quan (làm tròn đến 3 chữ số thập phân để thuận tiện):

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

Đây là một giải pháp hiện đại hơn, sử dụng dplyrgói (chưa tồn tại khi câu hỏi được hỏi):

Xây dựng đầu vào:

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

Tính toán các mối tương quan:

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

Đầu ra:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.