[英]outer() equivalent for non-vector lists in R
我了解在R中external()是如何工作的:
> outer(c(1,2,4),c(8,16,32), "*")
[,1] [,2] [,3]
[1,] 8 16 32
[2,] 16 32 64
[3,] 32 64 128
它基本上采用2個向量,找到這些向量的叉積,然后將函數應用於叉積中的每一對。
但是,我沒有兩個向量。 我有兩個矩陣列表:
M = list();
M[[1]] = matrix(...)
M[[2]] = matrix(...)
M[[3]] = matrix(...)
我想對矩陣列表進行操作。 我想要做:
outer(M, M, "*")
在這種情況下,我要獲取我擁有的每種矩陣組合的點積。
實際上,我正在嘗試生成內核矩陣(並且我已經編寫了內核函數),所以我想這樣做:
outer(M, M, kernelFunction)
其中, kernelFunction
計算兩個矩陣之間的距離。
問題在於,outer()僅接受“向量”參數,而不是“列表”等。是否有一個函數對非向量實體而言等效於outer()?
或者,我可以使用for循環來執行此操作:
M = list() # Each element in M is a matrix
for (i in 1:numElements)
{
for (j in 1:numElements)
{
k = kernelFunction(M[[i]], M[[j]])
kernelMatrix[i,j] = k;
}
}
但我試圖避免這種情況,而推薦使用R構造(可能會更有效)。 (是的,我知道我可以修改for循環以計算對角矩陣並節省50%的計算。但這不是我要優化的代碼!)
這可能嗎? 有什么想法/建議嗎?
外部函數確實在列表上起作用,但是您提供的函數會重復獲取兩個輸入向量,以便它們包含所有可能的組合...
至於哪一個更快,將external與vapply組合起來比我的機器上的double for循環快3倍。 如果實際的內核功能確實“起作用”,則循環速度的差異可能並不那么重要。
f1 <- function(a,b, fun) {
outer(a, b, function(x,y) vapply(seq_along(x), function(i) fun(x[[i]], y[[i]]), numeric(1)))
}
f2 <- function(a,b, fun) {
kernelMatrix <- matrix(0L, length(a), length(b))
for (i in seq_along(a))
{
for (j in seq_along(b))
{
kernelMatrix[i,j] = fun(a[[i]], b[[j]])
}
}
kernelMatrix
}
n <- 300
m <- 2
a <- lapply(1:n, function(x) matrix(runif(m*m),m))
b <- lapply(1:n, function(x) matrix(runif(m*m),m))
kernelFunction <- function(x,y) 0 # dummy, so we only measure the loop overhead
> system.time( r1 <- f1(a,b, kernelFunction) )
user system elapsed
0.08 0.00 0.07
> system.time( r2 <- f2(a,b, kernelFunction) )
user system elapsed
0.23 0.00 0.23
> identical(r1, r2)
[1] TRUE
只需使用for循環。 無論如何,任何內置函數都將退化為該函數,除非您仔細構建一個泛化到列表之外的函數,否則您將失去表達的清晰度。
您可以做的最大改進就是預分配矩陣:
M <- list()
length(M) <- numElements ^ 2
dim(M) <- c(numElements, numElements)
PS。 列表是一個向量。
盡管這是一個古老的問題,但這是另一個解決方案,它更多地體現了外部功能的精神。 這個想法是沿着list1和list2的索引應用外部的:
cor2 <- Vectorize(function(x,y) {
vec1 <- list1[[x]]
vec2 <- list2[[y]]
cor(vec1,vec2,method="spearman")
})
outer(1:length(list1), 1:length(list2), cor2)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.