2012-03-28 209 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

相关问题