2012-03-28 205 views
4

我試圖在R中創建各種距離/關聯函數的矩陣。我有一個類似於給出兩個向量之間關聯的cor的函數。現在我想獲取數字向量的數據幀(或矩陣),如mtcars,並從函數和數據幀中創建一個矩陣。我認爲這是outer是爲什麼,但我沒有得到它的工作。這是一個嘗試使用cor和mtcars從一個函數和兩個數字數據框中創建一個矩陣

cor(mtcars$mpg, mtcars$cyl) #a function that gives an association between two vectors     
outer(mtcars, mtcars, "cor") #the attempt to create a matrix of all vectors in a df 

是的我知道cor可以直接做到這一點,讓我們假裝它不能。該cor只是發現兩個向量之間的相關性。

所以最終的目標是獲得從cor(mtcars)得到的矩陣。

預先感謝您。

回答

8

您可以使用outer與需要列名或函數來對抗列號作爲參數。

outer(
    names(mtcars), 
    names(mtcars), 
    Vectorize(function(i,j) cor(mtcars[,i],mtcars[,j])) 
) 
+0

這兩個都是非常棒的點子。非常感謝你們。 +1 – 2012-03-29 00:12:04

+0

+1,適合使用'Vectorize'。 – Tommy 2012-03-29 00:14:28

3

outer不直接工作。它將只擴展它的XY載體,並呼叫cor一次。 編輯正如@Vincent Zoonekynd所示,您可以使其適應工作。

否則,一個相當簡單的循環的伎倆:

m <- as.matrix(mtcars) 
r <- matrix(1, ncol(m), ncol(m), dimnames=list(colnames(m), colnames(m))) 
for(i in 1:(ncol(m)-1)) { 
    for(j in (i+1):ncol(m)) { 
    r[i,j] <- cor(m[,i], m[,j]) 
    r[j,i] <- r[i,j] 
    } 
} 

all.equal(r, cor(m)) # Sanity check... 

r # print resulting 11x11 correlation matrix 

...在這裏,我假設你的關係是對稱的,COR(X,X)== 1

UPDATE由於文森特的解決方案是如此優雅得多,我有一個事實,即我的是快2倍:-)

# Huge data frame (1e6 rows, 10 cols) 
d <- data.frame(matrix(1:1e7, ncol=10)) 

# Vincent's solution  
system.time(outer(
    names(d), 
    names(d), 
    r <- Vectorize(function(i,j) cor(d[,i],d[,j])) 
)) # 2.25 secs 

# My solution  
system.time({ 
m <- d 
r <- matrix(1, ncol(m), ncol(m), dimnames=list(colnames(m), colnames(m))) 
for(i in 1:(ncol(m)-1)) { 
    for(j in (i+1):ncol(m)) { 
    r[i,j] <- cor(m[,i], m[,j]) 
    r[j,i] <- r[i,j] 
    } 
} 
}) # 1.0 secs 
+0

效果很好。 R是我唯一的語言,所以我不會在循環中自然地思考。謝謝。 +1 – 2012-03-29 00:12:41

相關問題