通过将函数应用于所有对来生成n维数组

时间:2017-04-12 17:52:20

标签: r multidimensional-array

F成为一个函数,它接受两个参数并返回一个数字 k - 向量(即一个长度为 k 的数字向量)的某个整数< EM>ķ&GT; 1,让XY成为适合作为F的第一和第二个参数的值的向量。

是否存在“功能性”(即无环路)且方便的方式来生成三维数组A,以便对于所有合适的ij,以下表达式为TRUE

all.equal(A[i, j, ], F(X[[i]], Y[[j]]))

更一般地说,让F成为一个函数,它接受两个参数并返回一个数字 n - 维数组(其中,dim(F(x, y)) = D是一个常量 n < / em> -vector,对于所有有效参数xy),和以前一样,让XY成为适合作为第一和第二个参数的值的向量(分别)F

是否有“功能”(即无环路)且方便的方式来生成( n + 2) - 维数组Adim(A)等于c(length(X), length(Y), D)),对于所有合适的ij,以下表达式为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的浮点数数组。 E.g:

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

1 个答案:

答案 0 :(得分:1)

好的,这是一个笨拙的解决方案。 我发布它希望能从一个比我更好地掌握R的人中找到一个更好的

outer_nd <- function(x, y, f) {
    pairs <- unname(as.matrix(expand.grid(x, y)))
    n <- nrow(pairs)
    rows <- split(pairs, seq(n))
    values <- sapply(rows, function (p) do.call(f, as.list(p)))
    array(t(values), dim = c(length(x), length(y), dim(F(x[[1]], y[[1]]))))
}

这个解决方案至少明确地说明了我的目标。

例如,如果F定义如下

F <- function (m, n) {
    set.seed(m - n);
    array(runif(6), dim = c(3, 2))
}

...然后

z <- outer_nd(1:2, 1:2, F)
dim(z)
 [1] 2 2 3 2

for (i in 1:2) {
    for (j in 1:2) {
        cat('\n', paste(c(i, j, '', ''), collapse = ', '), '\n')
        print(z[i, j, ,])

        cat('\nF(', paste(c(i, j), collapse = ', '), ') =\n')
        print(F(i, j))
        cat('\n')
    }
}
 1, 1, ,  
          [,1]      [,2]
[1,] 0.8966972 0.5728534
[2,] 0.2655087 0.9082078
[3,] 0.3721239 0.2016819

F( 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

F( 1, 2 ) =
          [,1]      [,2]
[1,] 0.4866672 0.1467027
[2,] 0.1913653 0.2415895
[3,] 0.9932719 0.5371012


 2, 1, ,  
          [,1]      [,2]
[1,] 0.2655087 0.9082078
[2,] 0.3721239 0.2016819
[3,] 0.5728534 0.8983897

F( 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

F( 2, 2 ) =
          [,1]      [,2]
[1,] 0.8966972 0.5728534
[2,] 0.2655087 0.9082078
[3,] 0.3721239 0.2016819