如何计算逻辑向量中的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条目的数目。