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

둘 다 정말 좋은 아이디어입니다. T는 너를 아주 많이 들었다. +1 –

+0

+1을 사용하면'Vectorize'를 유용하게 사용할 수 있습니다. – Tommy

3

outer은 작업에 직접적으로 미치지 않습니다. XY 벡터를 확장하고 cor으로 한 번 호출합니다. EDIT @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 

을 ... 여기에 내가 당신의 상관 관계가 대칭 및 코르 (X, X) == 1 가정.

UPDATE 빈센트의 솔루션은 훨씬 더 우아 때문에, 나는 나의

# 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 –

관련 문제