反面的

时间:2011-10-05 10:21:21

标签: r which

我错过了一些明显的东西吗?基本R中似乎缺少which的反函数(谷歌搜索,甚至搜索SO,因为“R inverse”会返回无数不相关的链接)?

好吧,不是说我不能写一个,而只是为了减轻我对失踪的挫折感,以及作为一个R-肌肉弯曲挑战:你会怎么写一个?

我们需要的功能如下:

invwhich<-function(indices, totlength)

返回长度为totlength的逻辑向量,其中indices中的每个元素都为TRUE,其余元素为FALSE

必然会有很多方法来实现这一点(其中一些方法确实很低调),因此争论为什么你的解决方案是“最好的”。 Oneliner有人吗?

如果它考虑了whicharr.ind ??)的其他一些参数,那显然更好......

6 个答案:

答案 0 :(得分:9)

单线解决方案:

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

答案 1 :(得分:5)

我自己的解决方案(现在):编辑按照@Marek的建议。

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。但是有可能把它变成一个oneliner吗?

表现,我只是使用:

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

作为一种非常低保真的绩效衡量标准。

答案 2 :(得分: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的工作! :)

答案 3 :(得分: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
}

答案 4 :(得分:0)

setdiff(1:total_length, indices)

答案 5 :(得分:0)

仅使用The new RDN will be <Old RDN>\0ACNF:<objectGUID> ,但将条件与`for key in dict: print(key) if dict[key] > 500: print('This costs more than 500' ) else: print('This costs less than 500.')` 相匹配:

which()