2011-10-05 7 views
9

私はここで何かが分かりませんか? whichの逆関数が基底Rに存在しないように見えます(グーグルで、 "R inverse"の無関係なリンクを返すためのSOの検索さえも)でしょうか?逆数のうち

私はそれを書くことはできませんが、それが欠けていることとR筋の屈曲の挑戦としての私の不満を和らげるために、あなたはどのように書くのでしょうか? indicesの各要素がTRUEで、残りはFALSE長さtotlengthの論理ベクトルを返す

invwhich<-function(indices, totlength) 

:我々は必要なもの

のような機能です。

これを達成する方法はたくさんありますが(そのうちのいくつかは実際にはぶら下がっている果物です)、なぜあなたのソリューションが「ベスト」なのかを主張してください。 Onelinerの誰ですか?

それは考慮にwhichの他のパラメータ(arr.ind ??)の一部を取る場合、それはさらに良い明らかだ...

+0

私は、これは 'の逆であるか分かりません」ケーキを作ることは、それを食べることの逆です。 'which'はあなたにベクトルのインデックスを与えるだけで、結果からベクトルの長さを知ることができないので、逆数を持つことはできません。従って、オンライナーのためにR. – John

答えて

7

ワンライナーソリューション:

invwhich <- function(indices, totlength) is.element(seq_len(totlength), indices) 

invwhich(c(2,5), 10) 
[1] FALSE TRUE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE 
+0

+1の 'invwhich'関数はありません。私の驚きにいくらか、パフォーマンスはそれほど良いものではありません(大きなベクトルと多くの繰り返しで目立ちますが)。 –

+2

むしろ、1ライナーが必ずしも「ベスト」ソリューションではないことを効果的に実証しています。 – Andrie

+1

'is.element'は'%in% 'と同じですので、代わりに' seq_len(totlength)%in%indices'です。 – Marek

5

私の独自のソリューション(のための今すぐ):EDIT @マレックの提案によると。

invwhich<-function(indices, outlength, useNames = TRUE) 
{ 
    rv<-logical(outlength) 
    #rv<-rep(FALSE, outlength) #see Marek's comment 
    if(length(indices) > 0) 
    { 
     rv[indices]<-TRUE 
     if(useNames) names(rv)[indices]<-names(indices) 
    } 
    return(rv) 
} 

それは可能な限りで、USENAMESを占め、非常によく実行する(Andrieのoneliner @よりも明らかに良い)と。しかし、これをオンライナーにすることは可能ですか?

WRTのパフォーマンスは、私は単純に使用:非常にローファイなパフォーマンス測定など

someindices<-sample(1000000, 500000, replace=FALSE) 
system.time(replicate(100, tmp<-invwhich(someindices, 1000000))) 

+1

'rep(FALSE、outlength)'を 'logical(outlength)'に置き換えることで、5倍速にすることができます。 – Marek

+0

あるいは、 'rep'を' rep.int'に置き換えてください。 – Marek

+0

これはオンライナーです: 'invwhich < - function(i、len) '[< - '(論理(len)、i、T)'。 (useNames)の場合は、次のようになります:useWindow(useNames)(ただし、誰がそれを必要としますか?): 'invwhich < - function(i、len、useNames = TRUE)setNames( '[< - '(論理(len)、i、T) (i)else NULL) ' –

1

別の変形、onelinerを作るために:

lWhich <- function(indices, totlength, vec = vector(length = totlength)){vec[indices] <- TRUE; return(vec)} 

私は簡潔にするため、異なる名前を好む:

lWhich <- function(ix, len, vec = vector(length = len)){vec[ix] <- TRUE; return(vec)} 

または、bitパッケージを使用して:

lWhichBit <- function(ix, len){return(as.logical(bitwhich(len, x = ix, poslength = length(ix))))} 

意外にも、それは遅いようです。コードによっては、repが使用されていることが判明しました。 !:(

これはRcppまたはcompileのための仕事です:)

指標のすべての種類を扱う
+0

"; " (もし私が時間があれば、私はいくつかのプロファイリングを行い、それがどうなったかを教えてくれるでしょう) –

+0

ああ、それは本当です;あなたにハエはありません。 :)遅かったです、私は何を言うことができます...私はリターンの中で課題をやろうとしましたが、それは乱雑になりました。 – Iterator

0

オーバーキル版:

#' Logical which 
#' 
#' Inverse of \link[base]{which}. 
#' Converts an array of any indices to a logical index array. 
#' 
#' Either \code{nms} or \code{len} has to be specified. 
#' 
#' @param idx  Numeric or character indices. 
#' @param nms  Array of names or a sequence. 
#'     Required if \code{idx} is a character array 
#' @param len  Length of output array. 
#'     Alternative to \code{nms} if \code{idx} is numeric 
#' @param useNames Use the names of nms or idx 
#' 
#' @examples 
#' all(lWhich(2, len = 3) == c(F, T, F)) 
#' all(lWhich(c('a', 'c'), letters[1:3]) == c(T, F, T)) 
#' 
#' @export 
lWhich <- function(idx, nms = seq_len(len), len = length(nms), useNames = TRUE) { 
    rv <- logical(len) 
    if (is.character(nms)) # we need names here so that rv[idx] works 
     names(rv) <- nms 

    if (useNames && !is.null(names(idx))) 
     names(rv)[idx] <- names(idx) 

    rv[idx] <- TRUE 

    if (!useNames) # if we don’t want names, we’ll remove them again 
     names(rv) <- NULL 
    rv 
} 
0
setdiff(1:total_length, indices) 
+2

これはここで使用される "逆"の意味ではありません。問題は、数のベクトルから真偽値のベクトル、すなわち「何」がその逆の方向に進むかということです。 –