2013-08-30 56 views
10

Tôi có một bộ dataframes lớn trông giống như A và B:Tính toán mối tương quan giữa hai dataframes yêu cầu một vòng lặp?

A <- data.frame(A1=c(1,2,3,4,5),B1=c(6,7,8,9,10),C1=c(11,12,13,14,15)) 

    A1 B1 C1 
1 1 6 11 
2 2 7 12 
3 3 8 13 
4 4 9 14 
5 5 10 15 

B <- data.frame(A2=c(6,7,7,10,11),B2=c(2,1,3,8,11),C2=c(1,5,16,7,8)) 

    A2 B2 C2 
1 6 2 1 
2 7 1 5 
3 7 3 16 
4 10 8 7 
5 11 11 8 

Tôi muốn tạo ra một vector (C) mà biểu thị tương quan Pearson giữa A1 & A2, B1 & B2 và C1 & C2. Trong trường hợp này, ví dụ, những mối tương quan là:

[1] 0.95 0.92 0.46 

Trả lời

13

cor chấp nhận hai data.frames:

A<-data.frame(A1=c(1,2,3,4,5),B1=c(6,7,8,9,10),C1=c(11,12,13,14,15)) 

B<-data.frame(A2=c(6,7,7,10,11),B2=c(2,1,3,8,11),C2=c(1,5,16,7,8)) 

cor(A,B) 

#   A2  B2  C2 
# A1 0.9481224 0.9190183 0.459588 
# B1 0.9481224 0.9190183 0.459588 
# C1 0.9481224 0.9190183 0.459588 

diag(cor(A,B)) 
#[1] 0.9481224 0.9190183 0.4595880 

Edit:

Dưới đây là một số tiêu chuẩn:

Unit: microseconds 
        expr  min  lq median  uq  max neval 
     diag(cor(A, B)) 230.292 238.4225 243.0115 255.0295 352.955 100 
     mapply(cor, A, B) 267.076 281.5120 286.8030 299.5260 375.087 100 
unlist(Map(cor, A, B)) 250.053 259.1045 264.5635 275.9035 1146.140 100 

Ed it2:

Và một số tiêu chuẩn tốt hơn sử dụng

set.seed(42) 
A <- as.data.frame(matrix(rnorm(10*n),ncol=n)) 
B <- as.data.frame(matrix(rnorm(10*n),ncol=n)) 

enter image description here

Tuy nhiên, tôi có lẽ nên đề cập đến rằng những tiêu chuẩn phụ thuộc rất nhiều vào số lượng hàng.

Chỉnh sửa3: Vì tôi đã được yêu cầu mã điểm chuẩn, ở đây.

b <- sapply(2^(1:12), function(n) { 
    set.seed(42) 
    A <- as.data.frame(matrix(rnorm(10*n),ncol=n)) 
    B <- as.data.frame(matrix(rnorm(10*n),ncol=n)) 

    require(microbenchmark) 
    res <- print(microbenchmark(
        diag(cor(A,B)), 
        mapply(cor, A, B), 
        unlist(Map(cor,A,B)), 
        times=10 
       ),unit="us") 
    res$median 
}) 

b <- t(b) 

matplot(x=1:12,log10(b),type="l", 
     ylab="log10(median [µs])", 
     xlab="log2(n)",col=1:3,lty=1) 
legend("topleft", legend=c("diag(cor(A, B))", 
          "mapply(cor, A, B)", 
          "unlist(Map(cor,A,B))"),lty=1, col=1:3) 
+4

+ 'diag' để chỉ nhận giá trị mà anh ấy quan tâm. – sgibb

+0

Cảm ơn, tôi vừa chuẩn bị bản chỉnh sửa. – Roland

+0

Có một hàm tương tự với 'cor' cung cấp các giá trị p của sự tương quan không? – dayne

7

Bạn có thể sử dụng một người bạn có chức năng áp dụng, Map, cho điều đó.

Map(function(x,y) cor(x,y),A,B) 
$A1 
[1] 0.9481224 

$B1 
[1] 0.9190183 

$C1 
[1] 0.459588 

Nếu bạn muốn đầu ra như vector theo đề nghị của @Jilber:

unlist(Map(function(x,y) cor(x,y),A,B)) 
     A1  B1  C1 
0.9481224 0.9190183 0.4595880 

Hoặc bạn chỉ có thể sử dụng:

unlist(Map(cor,A,B)) 
     A1  B1  C1 
0.9481224 0.9190183 0.459588 
+1

Vì OP muốn một vectơ, bạn nên sử dụng 'unlist (·)'. –

+0

Cảm ơn. Tôi sẽ cập nhật điều đó. – Metrics

+0

+1 cho một ví dụ điển hình của Bản đồ, tôi vẫn chưa hoàn toàn quấn quanh các khái niệm lập trình chức năng này trong R. –

6

Một lựa chọn khác bạn có thể sử dụng chức năng mapply

> mapply(function(x,y) cor(x,y),A,B) 
     A1  B1  C1 
0.9481224 0.9190183 0.4595880 

Hoặc jus t mapply(cor, A, B) theo đề xuất của @Aaron.

+3

Đây là những gì tôi muốn làm, mặc dù 'mapply (cor, A, B)' là đủ. – Aaron

+0

@Aaron cách người ta có thể áp dụng tư duy này vào danh sách các tệp cần có mối tương quan giữa chúng? Nói A .... Z? – KennyC

+0

@KennyC: Tốt hơn tôi nghĩ nên bắt đầu một câu hỏi mới; chi tiết hơn sẽ là cần thiết. – Aaron