我错过了一些明显的东西吗?基本R中似乎缺少which
的反函数(谷歌搜索,甚至搜索SO,因为“R inverse”会返回无数不相关的链接)?
好吧,不是说我不能写一个,而只是为了减轻我对失踪的挫折感,以及作为一个R-肌肉弯曲挑战:你会怎么写一个?
我们需要的功能如下:
invwhich<-function(indices, totlength)
返回长度为totlength
的逻辑向量,其中indices
中的每个元素都为TRUE
,其余元素为FALSE
。
必然会有很多方法来实现这一点(其中一些方法确实很低调),因此争论为什么你的解决方案是“最好的”。 Oneliner有人吗?
如果它考虑了which
(arr.ind
??)的其他一些参数,那显然更好......
答案 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()