2012-03-28 21 views
4

Rでさまざまな距離/関連関数の行列を作成しようとしています。これは2つのベクトル間の関連を与えるcorと似た関数です。今私はmtcarsのような数値ベクトルのデータフレーム(または行列)を取り、関数とデータフレームから行列を作成したいと考えています。私はこれがouterのものだと思っていましたが、うまく動作しません。 corとmtcarsを使って試してみましょう。関数と2つの数値データフレームから行列を作成する

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は、2つのベクトル間の相関を見つけるだけです。

最終的な目標は、cor(mtcars)から得る行列を得ることです。

ありがとうございます。

答えて

8

:-)あなたは、列名またはをとる関数でouterを使用することができます速い2倍であるという事実に対抗しなければなりません列番号を引数として指定します。

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 

...ここで私はあなたの相関関係が対称とCOR(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 –

関連する問題