15

do.call入力配列内のすべての次元の実際の範囲を特定する必要なく、サブセット化の式を作成できることを望んでいました。私が直面している問題は、直接関数を模倣する方法がわからないことですx[,,1:n,]。他の次元にエントリがないということは、「すべての要素を取得する」ことを意味します。

失敗するサンプル コードを次に示します。私が知る限り、リストの値をインデックスに置き換える[か、置き換えます。do.callNULL1

x<-array(1:6,c(2,3))
dimlist<-vector('list', length(dim(x)))
shortdim<-2
dimlist[[shortdim]] <- 1: (dim(x)[shortdim] -1)
flipped <- do.call(`[`,c(list(x),dimlist)) 

-2*max(dim(x))の各要素に値を割り当てることで解決策を見つけることができると思いますdimlistが、うんざりです。(FWIW、私は、または恐ろしい「文字列を構築してから」
を介して目的の仕事を行う代替機能を持っていますが、「より良い」ことをしたかったのです。)melt/recasteval(parse(mystring))

編集: 余談ですが、このコードのバージョン (DWin の TRUE セットアップと同等のもの) を、melt & acast;を使用する関数に対して実行しました。後者は何倍も遅く、驚くことではありませんでした。

4

5 に答える 5

9

直接的な答えではありませんが、asubこれがOPの最終的な目的であると確信しているため、代替としてデモを行います。

library(abind)

1 行目を抽出します。

asub(x, idx = list(1), dims = 1)

2 番目と 3 番目の列を抽出します。

asub(x, idx = list(2:3), dims = 2)

shortdimOPが望んでいたように、ディメンションから最後のアイテムを削除します。

asub(x, idx = list(1:(dim(x)[shortdim]-1)), dims = shortdim)

これも機能するように、負のインデックスを使用することもできます。

asub(x, idx = list(-dim(x)[shortdim]), dims = shortdim)

drop最後に、関数にはオプションがあることを述べておきます[

于 2013-07-19T17:23:01.317 に答える
1

OK、これが 4 つのバージョンのコードで、その後にmicrobenchmark. 速度は、これらすべてでほぼ同じように見えます。すべての回答が受け入れられているかどうかを確認したいのですが、それができないため、使用される安っぽい基準を次に示します。プレースホルダーに「TRUE」を入力する必要があるため、DWin は負けます。
flodel は、非ベース ライブラリが必要なため負けます。私のオリジナルはもちろん、eval(parse()). というわけでホンオイが勝利。彼は切り刻まれたアイドルになりたいの次のラウンドに進みます:-)

flip1<-function(x,flipdim=1) {
    if (flipdim > length(dim(x))) stop("Dimension selected exceeds dim of input")
    a <-"x["
    b<-paste("dim(x)[",flipdim,"]:1",collapse="")
    d <-"]"
    #now the trick: get the right number of commas
    lead<-paste(rep(',',(flipdim-1)),collapse="")
    follow <-paste(rep(',',(length(dim(x))-flipdim)),collapse="")
    thestr<-paste(a,lead,b,follow,d,collapse="")
    flipped<-eval(parse(text=thestr))
    return(invisible(flipped))
    }       

flip2<-function(x,flipdim=1) {
    if (flipdim > length(dim(x))) stop("Dimension selected exceeds dim of input")
    dimlist<-vector('list', length(dim(x))  )  
    dimlist[]<-TRUE  #placeholder to make do.call happy 
    dimlist[[flipdim]] <- dim(x)[flipdim]:1 
    flipped <- do.call(`[`,c(list(x),dimlist) )
    return(invisible(flipped))
    }       

# and another...
flip3 <- function(x,flipdim=1) {
    if (flipdim > length(dim(x))) stop("Dimension selected exceeds dim of input")
    flipped <- asub(x, idx = list(dim(x)[flipdim]:1), dims = flipdim)
    return(invisible(flipped))
}

#and finally, 
flip4 <- function(x,flipdim=1) {
    if (flipdim > length(dim(x))) stop("Dimension selected exceeds dim of input")
    dimlist <- rep(list(bquote()), length(dim(x)))
    dimlist[[flipdim]] <- dim(x)[flipdim]:1
    flipped<- do.call(`[`, c(list(x), dimlist))
    return(invisible(flipped))
}

Rgames> foo<-array(1:1e6,c(100,100,100))
Rgames> microbenchmark(flip1(foo),flip2(foo),flip3(foo),flip4(foo)


   Unit: milliseconds
       expr      min       lq   median       uq      max neval
 flip1(foo) 18.40221 18.47759 18.55974 18.67384 35.65597   100
 flip2(foo) 21.32266 21.53074 21.76426 31.56631 76.87494   100
 flip3(foo) 18.13689 18.18972 18.22697 18.28618 30.21792   100
 flip4(foo) 21.17689 21.57282 21.73175 28.41672 81.60040   100
于 2013-07-19T21:47:35.160 に答える
0

を使用substitute()して、空の引数を取得できます。これは通常のリストに含めることができます。

次に、可変数の空の引数をプログラムで生成するには、次のようにしますrep()

n <- 4
rep(list(substitute()), n)
于 2015-09-27T10:31:41.740 に答える