【发布时间】:2017-04-12 17:52:19
【问题描述】:
让F 成为一个函数,它接受两个参数并为某个整数返回一个数字 k-向量(即长度为 k 的数字向量) k > 1,并让X 和Y 成为适合作为F 的第一个和第二个参数(分别)的值的向量。
是否有一种“功能性”(即无循环)且方便的方式来生成 3 维数组 A,这样,对于所有合适的 i 和 j,以下表达式为 @987654328 @?
all.equal(A[i, j, ], F(X[[i]], Y[[j]]))
更一般地说,让F 是一个函数,它接受两个参数并返回一个数字 n 维数组(其中,dim(F(x, y)) = D 是一个常量 n-向量,对于所有有效参数 x 和 y),并且像以前一样,让 X 和 Y 是适合作为 F 的第一个和第二个参数(分别)的值的向量。
是否有一种“功能性”(即无循环)且方便的方法来生成 (n + 2) 维数组 A(其中 dim(A) 等于 @987654339 @) 这样,对于所有合适的i 和j,以下表达式为TRUE?
all.equal(A[i, j, , ... , ], F(X[[i]], Y[[j]]))
AFAICT,outer 不适用于此。例如,假设F 是这样定义的:
F <- function (m, n) {
set.seed(m - n);
array(runif(6), dim = c(3, 2))
}
这个F 接受两个整数作为参数,并返回一个 3 × 2 浮点数数组。例如:
F(3, 8)
[,1] [,2] [1,] 0.7345948 0.6368477 [2,] 0.3396928 0.9620946 [3,] 0.1910453 0.3756567
但是
outer(1:3, 1:3, Vectorize(F))
Error in outer(1:3, 1:3, Vectorize(F)) : dims [product 9] do not match the length of object [54]
我认为outer 在这里不起作用的原因是因为(强调)
外部(X, Y, FUN = "*", ...)
...
'FUN' 以这两个扩展向量作为参数调用(加上 '...' 中的任何参数)。它必须是矢量化函数(或 一个的名称)期望至少有两个参数并且返回一个 与第一个(和第二个)长度相同的值。
Vlo 更新:
## the line below is cut-and-paste'd directly from comment
F<-function(m,n){set.seed(m - n);list(array(runif(6), dim = c(3, 2)))}; x = outer(1:3, 1:5, Vectorize(F, "m", "n"))
如果我现在检查 x,我会得到:
x
[,1] [,2] [,3] [,4] [,5] [1,] Numeric,6 Numeric,6 Numeric,6 Numeric,6 Numeric,6 [2,] Numeric,6 Numeric,6 Numeric,6 Numeric,6 Numeric,6 [3,] Numeric,6 Numeric,6 Numeric,6 Numeric,6 Numeric,6
这不是我要找的。一方面,这里的dim(x) 等于向量c(3, 5),而对于所需的x,它应该是那个
dim(x)
[1] 3 5 3 2
和
for (i in 1:3) {
for (j in 1:5) {
cat('\n', paste(c(i, j, '', ''), collapse = ', '), '\n')
print(x[i, j, ,])
}
}
1, 1, , [,1] [,2] [1,] 0.8966972 0.5728534 [2,] 0.2655087 0.9082078 [3,] 0.3721239 0.2016819 1, 2, , [,1] [,2] [1,] 0.4866672 0.1467027 [2,] 0.1913653 0.2415895 [3,] 0.9932719 0.5371012 1, 3, , [,1] [,2] [1,] 0.8141134 0.2416691 [2,] 0.5890751 0.9928682 [3,] 0.1339374 0.9844079 1, 4, , [,1] [,2] [1,] 0.7705233 0.3878055 [2,] 0.7820377 0.1221871 [3,] 0.3802074 0.3378332 1, 5, , [,1] [,2] [1,] 0.38668404 0.7800617 [2,] 0.09064471 0.4887107 [3,] 0.65027437 0.9742584 2, 1, , [,1] [,2] [1,] 0.2655087 0.9082078 [2,] 0.3721239 0.2016819 [3,] 0.5728534 0.8983897 2, 2, , [,1] [,2] [1,] 0.8966972 0.5728534 [2,] 0.2655087 0.9082078 [3,] 0.3721239 0.2016819 2, 3, , [,1] [,2] [1,] 0.4866672 0.1467027 [2,] 0.1913653 0.2415895 [3,] 0.9932719 0.5371012 2, 4, , [,1] [,2] [1,] 0.8141134 0.2416691 [2,] 0.5890751 0.9928682 [3,] 0.1339374 0.9844079 2, 5, , [,1] [,2] [1,] 0.7705233 0.3878055 [2,] 0.7820377 0.1221871 [3,] 0.3802074 0.3378332 3, 1, , [,1] [,2] [1,] 0.1848823 0.1680519 [2,] 0.7023740 0.9438393 [3,] 0.5733263 0.9434750 3, 2, , [,1] [,2] [1,] 0.2655087 0.9082078 [2,] 0.3721239 0.2016819 [3,] 0.5728534 0.8983897 3, 3, , [,1] [,2] [1,] 0.8966972 0.5728534 [2,] 0.2655087 0.9082078 [3,] 0.3721239 0.2016819 3, 4, , [,1] [,2] [1,] 0.4866672 0.1467027 [2,] 0.1913653 0.2415895 [3,] 0.9932719 0.5371012 3, 5, , [,1] [,2] [1,] 0.8141134 0.2416691 [2,] 0.5890751 0.9928682 [3,] 0.1339374 0.9844079
【问题讨论】:
-
这真的取决于细节以及“无循环”的含义。如果将向量(而不是单个值)传递给
F的任一参数,会发生什么情况?你能调整F使其能够处理矢量化吗?最终,F做了什么?无论如何,你可以通过expand.grid和mapply的组合来实现你想要的,但几乎不能定义为loop-free。 -
我不完全明白你在追求什么,但它听起来像是
mapply的工作。至少第一部分可以。 -
F<-function(m,n){set.seed(m - n);list(array(runif(6), dim = c(3, 2)))}; x = outer(1:3, 1:5, Vectorize(F, "m", "n"))有效。Vectorize只是一个很大的旧循环。 -
@Frank:对此感到抱歉(已修复)。
-
@Vlo:您发布的 sn-p 不会产生正确的结果。 (在我对问题的回答中,我举了一个期望输出的例子。)