1

我正在尝试对所有可能的向量组合执行点积。我能够找到所有可能的组合。我只是不太明白 combn() 中的 FUN 参数是如何工作的。以下是我的代码,感谢您的帮助!

def=c("Normal.def","Fire.def","Water.def","Electric.def","Grass.def","Ice.def",
       "Fighting.def","Poison.def","Ground.def","Flying.def","Pyschic.def","Bug.def",
       "Rock.def","Ghost.def","Dragon.def","Null.def")

combn(def,2,FUN=def%*%def,simplify=TRUE)
4

2 回答 2

5

使用@BrodieG 的示例数据,您可以只使用该crossprod函数:

set.seed(1)
vec1 <- sample(1:10)
vec2 <- sample(1:10)
vec3 <- sample(1:10)

crossprod(cbind(vec1, vec2, vec3))
#      vec1 vec2 vec3
# vec1  385  298  284
# vec2  298  385  296
# vec3  284  296  385

出于好奇,一些基准测试:

要运行的功能:

fun1 <- function() {
  A <- crossprod(do.call(cbind, lst))
  A[upper.tri(A)]
} 
fun2 <- function() {
  A <- do.call(rbind, lst) %*% do.call(cbind, lst)
  A[upper.tri(A)]
} 
fun3 <- function() {
  combn(
    seq_along(lst), 2, 
    FUN=function(idx) c(lst[[idx[[1]]]] %*% lst[[idx[[2]]]])
  )
}

“少量大向量”的基准测试。

library(microbenchmark)

set.seed(1)
n <- 5
lst <- setNames(replicate(n, sample(1:100000), simplify = FALSE), 
                paste0("V", sequence(n)))

microbenchmark(fun1(), fun2(), fun3())
# Unit: milliseconds
#    expr       min        lq    median        uq      max neval
#  fun1()  6.909651  6.992031  8.432346  8.520301 74.12263   100
#  fun2() 17.290101 18.811134 19.144601 21.292544 88.10602   100
#  fun3() 22.841209 24.283113 24.427876 25.820158 91.14007   100

没有足够的耐心对中等数量的中等向量进行基准测试:

set.seed(1)
n <- 1000
lst <- setNames(replicate(n, sample(1:1000), simplify = FALSE), 
                paste0("V", sequence(n)))

system.time(fun1())
#   user  system elapsed 
#  0.245   0.004   0.251 

system.time(fun2())
#   user  system elapsed 
#  0.407   0.016   0.425 

system.time(fun3())
#   user  system elapsed 
# 14.216   0.004  14.339 
于 2014-04-17T18:23:44.530 回答
3

你为什么不只是矩阵乘以整个事情。例如:

set.seed(1)
vec1 <- sample(1:10)
vec2 <- sample(1:10)
vec3 <- sample(1:10)

rbind(vec1, vec2, vec3) %*% cbind(vec1, vec2, vec3)

产生:

     vec1 vec2 vec3
vec1  385  298  284
vec2  298  385  296
vec3  284  296  385

其中矩阵的每个单元格是 col 和 row 标签中两个向量的点积。或者,如果你真的想这样做combn

vec.lst <- list(vec1, vec2, vec3)
combn(
  seq_along(vec.lst), 2, 
  FUN=function(idx) c(vec.lst[[idx[[1]]]] %*% vec.lst[[idx[[2]]]])
)

产生:

[1] 298 284 296

请注意这些数字如何对应于矩阵的上三角形。对于小数据集,矩阵乘法方法要快得多。对于大型的,特别是那些向量非常大但数量不多的向量,这种combn方法可能会更快,因为它不会运行尽可能多的计算(基本上只有上三角形)。

于 2014-04-17T18:12:12.297 回答