2017-06-22 15 views
2

私は2つのベクトルを取り、1つの要素の数を他のベクトルにも含めて返します。同様:n * m行列のすべての列の組み合わせでm * mの結果を返す関数

f <- function(v1,v2)sum(v1 %in% v2) 

どのようにして、n個の* mの行列におけるm列のすべてのペアごとの組み合わせに、その関数を適用することができます。

set.seed(1) 
m <- replicate(3, sample(letters[1:10], size = 5)) 
dimnames(m) <- list(NULL, paste0('c', 1:ncol(m))) 

さて、

> m 
    [,1] [,2] [,3] 
[1,] "c" "i" "c" 
[2,] "d" "j" "b" 
[3,] "e" "f" "f" 
[4,] "g" "e" "j" 
[5,] "b" "a" "e" 

そして、最初の2つの列に機能を取る:

> f(m[,1], m[,2]) 
[1] 1 #'e' is shared. 

すべての列の組み合わせでそれを行うには?結果は、am * m行列(結果が対角線の周りで対称である)であるか、v1、v2の列と関数の結果を持つlong形式のデータフレームである可能性があります(たとえば、最初の行はc1c23

私は機能outerexpand.gridを調査しようとしましたが、解決策を見つけることができませんでした。

+1

でこれを行うことができます 'crossprod(表(メートル、COL(M)))' –

答えて

2
sapply(1:3, function(i) sapply(1:3, function(j) f(m[,i], m[,j]))) 
#  [,1] [,2] [,3] 
#[1,] 5 1 3 
#[2,] 1 5 3 
#[3,] 3 3 5 

または、次の出力は、二重ループも動作します

sapply(data.frame(m), function(x1) sapply(data.frame(m), function(x2) f(x1, x2))) 
# c1 c2 c3 
#c1 5 1 3 
#c2 1 5 3 
#c3 3 3 5 
0

友好かもしれません。唯一の事は、私がデータフレームMするmを変換されます

f <- function(v1,v2)sum(v1 %in% v2) 
set.seed(1) #Leads to different m values than you posted 
m <- replicate(3, sample(letters[1:10], size = 5)) 
dimnames(m) <- list(NULL, paste0('c', 1:ncol(m))) 

#Convert m to dataframe M 
M <- as.data.frame(m) 

#Initialize dataframe of answers 
df <- data.frame(matrix(ncol=3, nrow=ncol(M))) 

#Loop and get answers 
row <- 1 
for(i in 1:(ncol(M)-1)){ 
    for(j in 1:(ncol(M)-i)){ 
    df[row, 1] <- names(M)[i] 
    df[row, 2] <- names(M)[i+j] 
    df[row, 3] <- f(M[,i], M[,i+j]) 
    row <- row+1 
    } 
} 

df 
    X1 X2 X3 
1 c1 c2 1 
2 c1 c3 3 
3 c2 c3 3 
2

すべての組み合わせを得るためにexpand.gridを使用して、ペアによるその後、ループが交差する項目の長さを取得します。

myComb <- expand.grid(colnames(m), colnames(m)) 

myComb$N <- apply(myComb, 1, function(i){ 
    length(intersect(m[, i[1]], m[, i[2]])) 
    # or use your own function 
    # f(m[, i[1]], m[, i[2]]) 
}) 

myComb 
# Var1 Var2 N 
# 1 c1 c1 5 
# 2 c2 c1 1 
# 3 c3 c1 3 
# 4 c1 c2 1 
# 5 c2 c2 5 
# 6 c3 c2 3 
# 7 c1 c3 3 
# 8 c2 c3 3 
# 9 c3 c3 5 
+0

ニースソリューションも参照: '適用のあなたの出力を取り出します... '行列(出力、ncol = 3)を簡単に作ることができます。あまりにもOPが出力形式を指定していない。 – CPak

1

我々は、この特定のケースではouter

f1 <- function(x, y) length(intersect(m[,x], m[,y])) 
res <- outer(colnames(m), colnames(m), FUN = Vectorize(f1)) 
dimnames(res) <- list(colnames(m), colnames(m)) 
res 
# c1 c2 c3 
#c1 5 1 3 
#c2 1 5 3 
#c3 3 3 5 
関連する問題