2017-06-22 102 views
2

說我有一個函數,它需要兩個向量並返回一個整數,例如一個元素的數量也在另一個向量中。如: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" 

,並就前兩列的功能:

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

如何做到這一點的所有列的組合?結果可能是am * m矩陣(結果對稱於對角線),或者,也可能是一個長格式的數據框,其中包含v1,v2列和函數的結果(例如,第一行將是c1c23

我試圖調查功能outerexpand.grid但找不到解決方案。

+1

做到這一點對於這個特定的情況下,又見'crossprod(表(男,山坳(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