Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 如何将外维度推广到n维?_R_Vectorization_Reduce_Outer Join - Fatal编程技术网

R 如何将外维度推广到n维?

R 如何将外维度推广到n维?,r,vectorization,reduce,outer-join,R,Vectorization,Reduce,Outer Join,标准R表达式outer(X,Y,f)计算为一个矩阵,其(i,j)第个条目的值f(X[i],Y[j]) 我想实现函数multi.outer,这是outer的一个n维泛化:multi.outer(f,X_1,…,X_n),其中f是一些n元函数,它将生成一个(length(X_1)*length(X_n)数组,其(I_1,…,I_n)第个条目的值为f(X_1[I_1],…,X_n[I_n])适用于所有有效索引集(i_1,…,i_n)。显然,对于{1,…,n}中的每个i,X_iinmulti.outer

标准R表达式
outer(X,Y,f)
计算为一个矩阵,其(i,j)第个条目的值
f(X[i],Y[j])

我想实现函数
multi.outer
,这是
outer
的一个n维泛化:
multi.outer(f,X_1,…,X_n)
,其中f是一些n元函数,它将生成一个(length(X_1)*length(X_n)数组,其(I_1,…,I_n)第个条目的值为
f(X_1[I_1],…,X_n[I_n])
适用于所有有效索引集(i_1,…,i_n)。显然,对于{1,…,n}中的每个i,
X_i
in
multi.outer(f,X_1,…,X_i,…,X_n)
的所有元素必须是函数
f
允许的第i个参数。对于n=2的情况,
multi.outer
将执行与
outer
相同的操作,尽管它将具有不同的签名(IOW,
multi.outer(f,X,Y)
将等同于
outer(X,Y,f)

需要注意的是,尽管
multi.outer
的参数X_1,…,X_n都是向量,但它们不一定都具有相同的模式。例如,X_1和X_2可以分别是
c(1,2,3)
字母[10:20]

谢谢

这个怎么样:


multi.outer<-function(f,...){

  apply(expand.grid(...),1,function(x){do.call(f,as.list(x))})

}


multi.outer这是一种方法:首先使用
Vectorize
outer
定义一个函数,该函数创建一个n维矩阵,其中每个条目都是一个参数列表,给定函数将应用于此参数:

list_args <- Vectorize( function(a,b) c( as.list(a), as.list(b) ), 
                        SIMPLIFY = FALSE)


make_args_mtx <- function( alist ) {
  Reduce(function(x, y) outer(x, y, list_args), alist)
}
让我们用一个示例函数来尝试:

fun <- function(a,b,c) paste(a,b,c)

ans <- multi.outer(fun, LETTERS[1:2], c(3, 4, 5), letters[6:7] )

> ans
, , 1

     [,1]    [,2]    [,3]   
[1,] "A 3 f" "A 4 f" "A 5 f"
[2,] "B 3 f" "B 4 f" "B 5 f"

, , 2

     [,1]    [,2]    [,3]   
[1,] "A 3 g" "A 4 g" "A 5 g"
[2,] "B 3 g" "B 4 g" "B 5 g"

fun我想我们可以使用Outer和Vectorize来实现这一点

 sigm = function(a=0,b=0,x){
 return(exp(x*a+b))
 }

 sigm1 = Vectorize(function(a=-1:1,b=-1:1,x){

 outer(a,b,sigm,x)
 },SIMPLIFY = FALSE)
现在,sigm1(x=1:3)给出了所需的输出

 [[1]]
      [,1]      [,2]     [,3]
 [1,] 0.1353353 0.3678794 1.000000
 [2,] 0.3678794 1.0000000 2.718282
 [3,] 1.0000000 2.7182818 7.389056

[[2]]
       [,1]      [,2]       [,3]
[1,] 0.04978707 0.1353353  0.3678794
[2,] 0.36787944 1.0000000  2.7182818
[3,] 2.71828183 7.3890561 20.0855369

[[3]]
       [,1]        [,2]       [,3]
[1,] 0.01831564  0.04978707  0.1353353
[2,] 0.36787944  1.00000000  2.7182818
[3,] 7.38905610 20.08553692 54.5981500
这个代码片段的唯一缺点是我使用了默认值a=-1:1和b=-1:1。当我试图在函数调用过程中传递相同的消息时,它就失控了。例如

sigm1(-1:1,-1:1,1:3)

[[1]]
      [,1]
[1,] 0.1353353

[[2]]
 [,1]
[1,]    1

[[3]]
     [,1]
[1,] 54.59815

我无法理解为什么传递参数会使输出产生这种差异

我相信OP希望结果是在一个n维矩阵中,每个维对应于
f
+1的每个参数,以使我意识到
expand.grid
,但是当我尝试使用测试函数
function(s,b,l){substr(s,b,b+l-1)
进行此
multi.outer
(第一次)时,和
c(“ABCDEFGH”,“IJKLMNOP”,“qrstuvxx”),1:5,2:3
作为其余的参数,我得到了函数中的
错误(s,b,l):未使用的参数(Var1=“ABCDEFGH”,Var2=“1”,Var3=“2”)
。我还没有机会弄清楚您的实现是做什么的,或者为什么会出现这个错误。很好!请参见一个具有类似答案的类似问题(但不是那么复杂):
sigm1(-1:1,-1:1,1:3)

[[1]]
      [,1]
[1,] 0.1353353

[[2]]
 [,1]
[1,]    1

[[3]]
     [,1]
[1,] 54.59815