如何计算逻辑向量中的TRUE值

在R中,计算逻辑向量中的TRUE值的数量的最有效/惯用的方法是什么? 我可以想到两种方法:

 z <- sample(c(TRUE, FALSE), 1000, rep = TRUE) sum(z) # [1] 498 table(z)["TRUE"] # TRUE # 498 

你喜欢哪个? 还有什么更好的吗?

当逻辑向量包含NA值时会出现一些问题。
看例如:

 z <- c(TRUE, FALSE, NA) sum(z) # gives you NA table(z)["TRUE"] # gives you 1 length(z[z==TRUE]) # f3lix answer, gives you 2 (because NA indexing returns values) 

所以我觉得安全

 sum(z, na.rm=TRUE) # best way to count TRUE values 

(这给出1)。 我认为table解决scheme效率较低(查看table函数的代码)。

此外,如果逻辑向量中没有TRUE值,则应该小心“表”解决scheme。 假设z <- c(NA, FALSE, NA)或者简单地z <- c(FALSE, FALSE)

 table(z)["TRUE"] # gives you NA for both cases. 

没有提到的另一个select是使用which

 length(which(z)) 

只是为了在“哪个问题更快”中提供一些背景知识,通常只需要testing自己就可以了。 我做了比较大的载体:

 z <- sample(c(TRUE,FALSE),1000000,rep=TRUE) system.time(sum(z)) user system elapsed 0.03 0.00 0.03 system.time(length(z[z==TRUE])) user system elapsed 0.75 0.07 0.83 system.time(length(which(z))) user system elapsed 1.34 0.28 1.64 system.time(table(z)["TRUE"]) user system elapsed 10.62 0.52 11.19 

所以在这种情况下,清楚地使用sum是最好的方法。 Marekbuild议您也可以检查NA值。

只需添加关于NA值和which函数的注释:

 > which(c(T, F, NA, NULL, T, F)) [1] 1 4 > which(!c(T, F, NA, NULL, T, F)) [1] 2 5 

请注意,它只检查逻辑TRUE ,所以它实际上忽略了非逻辑值。

另一种方法是

 > length(z[z==TRUE]) [1] 498 

虽然sum(z)很好,但对我而言, length(z[z==TRUE])更能自我解释。 尽pipe如此,我认为通过这样一个简单的任务它并没有真正有所作为。

如果它是一个大的vector,你可能应该用最快的解决scheme,这是sum(z)length(z[z==TRUE])大约慢10倍,而table(z)[TRUE]大约比sum(z)慢200倍。

总结一下, sum(z)是键入和执行的最快速度。

which是很好的select,特别是当你在matrix上操作时(检查?which并注意到arr.ind参数)。 但是我build议你坚持一下,因为na.rm论据可以处理NA的逻辑向量。 例如:

 # create dummy variable set.seed(100) x <- round(runif(100, 0, 1)) x <- x == 1 # create NA's x[seq(1, length(x), 7)] <- NA 

如果你inputsum(x)你将得到NA ,但是如果你在sum函数中传递na.rm = TRUE ,你会得到你想要的结果。

 > sum(x) [1] NA > sum(x, na.rm=TRUE) [1] 43 

你的问题是严格的理论,还是你有一些关于逻辑向量的实际问题?

另一个select是使用汇总function。 它给出了Ts,Fs和NAs的总结。

 > summary(hival) Mode FALSE TRUE NA's logical 4367 53 2076 > 

几个星期前我一直在做类似的事情。 这是一个可能的解决scheme,它是从头开始编写的,所以它是一种beta版本或类似的东西。 我会尝试通过从代码中删除循环来改善它…

主要想法是写一个函数,将采取2(或3)参数。 首先是一个数据data.frame ,其中包含从调查问卷收集的数据,第二个是有正确答案的数字向量(这仅适用于单选题问卷)。 或者,您可以添加第三个参数,该参数将返回带有最终分数的数字向量,或者带有embedded分数的data.frame。

 fscore <- function(x, sol, output = 'numeric') { if (ncol(x) != length(sol)) { stop('Number of items differs from length of correct answers!') } else { inc <- matrix(ncol=ncol(x), nrow=nrow(x)) for (i in 1:ncol(x)) { inc[,i] <- x[,i] == sol[i] } if (output == 'numeric') { res <- rowSums(inc) } else if (output == 'data.frame') { res <- data.frame(x, result = rowSums(inc)) } else { stop('Type not supported!') } } return(res) } 

我会试着用一些更加优雅的方式来做这件事。 请注意,我没有把na.rm论点…会做到这一点

 # create dummy data frame - values from 1 to 5 set.seed(100) d <- as.data.frame(matrix(round(runif(200,1,5)), 10)) # create solution vector sol <- round(runif(20, 1, 5)) 

现在应用一个函数:

 > fscore(d, sol) [1] 6 4 2 4 4 3 3 6 2 6 

如果你传递data.frame参数,它将返回修改的data.frame。 我会尝试修复这个…希望它有帮助!

我刚刚有一个特殊的问题,我不得不从一个逻辑向量计算真正的语句的数量,这对我来说是最好的… …

 length(grep(TRUE, (gene.rep.matrix[i,1:6] > 1))) > 5 

所以这需要gene.rep.matrix对象的一个​​子集,并应用逻辑testing,返回一个逻辑向量。 这个向量作为grep的一个参数,它返回任何TRUE条目的位置。 长度然后计算grepfind多less条目,从而给出TRUE条目的数目。