2017-12-13 17 views
0

かなり多次元の配列で作業していますが、可変ディメンションの配列からサブアレイを動的に抽出するためのabind-package方法(abind::asub)が本当に好きです。R:サブアレイを動的に置き換える

しかし、逆の操作、つまりサブアレイを別の配列で動的に置き換える効率的な方法を探したいと思います。 '[<-' -functionで添字を使用してのベースRの方法は

library(abind) # just to show the wanted dynamical indexing 
library(microbenchmark) # speed is essential 

array.goal<-array.test<-array.original<-array(rnorm(100000),dim=c(10,10,10,10,10)) 
array.replacement<-array(1,dim=c(10,10,5,10,10)) 

microbenchmark(array.goal[,,3:7,,]<-array.replacement) # mean 507.9323 microseconds 

十分に速いですが、それは動的ではありません - 私は変数をターゲット寸法を設定していないコンマの固定数を書き留めることができるようにしたいです。 ASUBと同じスタイルは、抽出に使用していますサブアレイインデックスの行列を生成することによって

# the variables to control the replacement location: 
dims<-3 
idx<-list(3:7) 
# i.e. want to be able to use the same kind of notation that abind::asub 
# uses for extracting the sub arrays, as in: 
identical(asub(array.goal,dims=dims,idx=idx),array.replacement) 

以下の作品が、それは私の好みのために遅すぎる:で使用

findsubi<-function(x,idx,dims){ 
    dim.x<-dim(x) 
    dim.length<-length(dim.x) 
    stopifnot(all(dims>=0) & all(dims<=dim.length),class(idx)=="list") 
    stopifnot(dim.x[dims]>=lapply(idx,max)) 
    allowed<-lapply(dim.x,FUN=function(x){1:x}) 
    allowed[dims]<-idx 
    index.space<-as.matrix(expand.grid(allowed)) 
    return(index.space) 
} 

# slooower: mean 4.259752 milliseconds! 
microbenchmark(array.test[findsubi(array.test,dims=dims,idx=idx)]<-array.replacement) 
identical(array.test,array.goal) # i know they are. 

標準subreplacement機能'[<-'目標を生成するための開始は私にとっては十分に速いので、必要な引数/添え字(たとえば、3:7 ,,)を素早く生成するラッパーを書くことができます所望のサブアレイを定義する個々のインデックスのベクトルを作成する

ので、本質的に、私は

# let's go back to square one: 
array.test<-array.original 


asubassi<-function(x,dims,idx,y){ 
    # steps to generate ",,3:7,," 
    #argum<-something.to.generate.them(x,dims,idx) 
    # i'd like to be able to efficiently generate the subscripts dynamically, 
    # but I don't know how 
    # you can't just generate a string and use that: 
    # argum<-',,3:7,,' the line '[<-'(x,argum,y) would fail 

'[<-'(x,,,3:7,,,y) # now just an example with a fixed subarray 

} 

うまくいけば、それはまだ

# mean 620.7229 microseconds 
microbenchmark(array.test<- 
asubassi(x=array.test,dims=dims,idx=idx,y=array.replacement)) 

identical(array.test,array.goal) # the truth is out there! 

十分に速くなり、力学abind::asubスタイル力学インデックスでラッパーを持っていると思い動的に必要なを生成して渡す方法がありますサブスクリプト - 基本的な引数を[<-に置き換えますか?または、多次元サブアレイの高速動的置換の目標を達成するための他の方法。

+0

これは 'do.call'の仕事のようです。 – JDL

+0

あなたは[ここ](https://stackoverflow.com/questions/17750893/how-to-pass-nothing-as-an-argument-to-for-subsetting)同様の投稿を見ることができました –

+0

ありがとうJDLとalexis_laz! 'do.call'と適切なリスト(ほとんど空の要素のリスト)はこれを行うための非常に良い方法のようです。 – lohisoturi

答えて

1

@ JDLと@alexis_lazのおかげで彼らの助けになりました。

# mean 773.6759 microseconds 
microbenchmark(array.test<- 
asubassi(x=array.test,dims=dims,idx=idx,y=array.replacement)) 
identical(array.test,array.goal) # yep 

ありがとう:解決策は、最初の動的速度は十分ですdo.call

subarray.argument<-function(x,dims,idx){ 
    dim.x<-dim(x) 
    dim.length<-length(dim.x) 
    stopifnot(all(dims>=0) & all(dims<=dim.length),class(idx)=="list") 
    stopifnot(dim.x[dims]>=lapply(idx,max)) 
    # first a suitable empty list 
    argument<-rep(list(bquote()),dim.length) 
    argument[dims]<-idx # insert the wanted dimension slices 
return(argument) 
} 

asubassi<-function(x,dims,idx,y){ 
    argum<-c(alist(x),subarray.argument(x,dims,idx),alist(y)) 
    do.call('[<-',argum) 
} 

のための適切なリストを生成することです!

関連する問題