假设我有一个函数,它接受两个向量并返回一个整数,例如一个元素的数量也在另一个向量中。像:
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列和函数结果的长格式数据帧(例如第一行)将是c1
,c2
和3
)
我尝试调查函数outer
和expand.grid
,但无法找到解决方案。
答案 0 :(得分: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
答案 1 :(得分: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
答案 2 :(得分: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
答案 3 :(得分: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