2011-10-05 48 views
9

我在這裏錯過了一些明顯的東西嗎?它看起來which的反函數從基礎R(谷歌搜索,甚至搜索SO「R反向」返回無數不相關的鏈接)?其中反向

嗯,不是我不能寫一個,而僅僅是爲了減輕我對它失蹤的挫折感,並且作爲一個R肌肉彎曲的挑戰:你將如何去寫一個?

我們需要的是像一個函數:

invwhich<-function(indices, totlength) 

返回長度totlength的邏輯矢量,其中在indices每個元素是TRUE,其餘是FALSE

一定會有很多方法來完成這個(其中有些是非常低的掛果),所以爭論爲什麼你的解決方案是'最好的'。 Oneliner有人嗎?

如果考慮到一些whicharr.ind?)其它參數,這顯然是更好的...

+0

我不知道這是'逆which'。這就像說做蛋糕是吃一個蛋糕的反面。你不能有一個逆,因爲'which'只給你一個向量的索引,你不能從結果中知道向量的長度。因此,對於oneliner,在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

相當有效地證明單行者並不總是「最好」的解決方案。 – Andrie

+1

'is.element'與'%in%'相同,因此替代方法是%index中的seq_len(totlength)%。 – Marek

5

自己的解決方案(爲現在):編輯根據@馬立克的建議。

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) 
} 

它有很好的表現(明顯高於@ Andrie的oneliner更好),並在儘可能多的,佔USENAMES。但是有可能把它變成一個在線的?

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.int'替換'rep'。 – Marek

+0

這將是oneliner:'invwhich < - function(i,len)'[< - '(logical(len),i,T)'。或useNames(但是誰需要那個?):'invwhich < - 函數(i,len,useNames = TRUE)setNames('[< - '(邏輯(len),i,T),if(useNames) (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

使用「;」等同於沒有一個在線...但是,我會爲你付出努力的+1(如果我有時間,我會做一些分析並讓你知道它是怎麼回事) –

+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

這不是在這裏使用的「反」的意思。問題是關於從一個數字向量到一個真/假向量向量,也就是說,哪個「做」,但在相反的方向。 –