在R中,計算邏輯向量中TRUE
值的數量的最有效/慣用的方法是什麼?我可以想到兩種方法:如何計算邏輯向量中的TRUE值
z <- sample(c(TRUE, FALSE), 1000, rep = TRUE)
sum(z)
# [1] 498
table(z)["TRUE"]
# TRUE
# 498
你更喜歡哪一種?有什麼更好的嗎?
在R中,計算邏輯向量中TRUE
值的數量的最有效/慣用的方法是什麼?我可以想到兩種方法:如何計算邏輯向量中的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
解決方案效率較低(請參閱table
函數的代碼)。
另外,在邏輯向量中沒有TRUE值的情況下,您應該小心「表」解決方案。假設z <- c(NA, FALSE, NA)
或者乾脆z <- c(FALSE, FALSE)
table(z)["TRUE"] # gives you NA for both cases.
另一種方式是
> length(z[z==TRUE])
[1] 498
雖然sum(z)
是美好而短暫,我length(z[z==TRUE])
是更多的自我解釋。雖然,我認爲通過這樣一個簡單的任務它並沒有真正有所作爲...
如果它是一個很大的向量,你可能應該使用最快的解決方案,即sum(z)
。 length(z[z==TRUE])
約慢10倍,table(z)[TRUE]
比sum(z)
慢約200倍。
總結,sum(z)
是鍵入和執行最快的。
尚未提到的另一種選擇是使用which
:
length(which(z))
只是實際提供一些背景的「這是更快的問題」,它總是最容易只是爲了測試自己。我做了很多比較大的載體:所以很明顯使用sum
在這種情況下,最好的辦法
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
。 Marek建議您也可以檢查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
檢查,所以它基本上忽略非邏輯值。
which
是很好的選擇,尤其是當您在矩陣上操作時(請檢查?which
並注意arr.ind
參數)。但我建議你堅持sum
,因爲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
如果您在sum(x)
鍵入你會得到NA
結果,但如果你在sum
功能通過na.rm = TRUE
,你會得到你想要的結果。
> sum(x)
[1] NA
> sum(x, na.rm=TRUE)
[1] 43
你的問題是嚴格的理論,還是你有一些關於邏輯向量的實際問題?
我試圖年級測驗。在應用中做類似sum(youranswer == rightanswer)的事情。 – 2010-02-05 06:55:21
我的回覆太長了,所以我發佈了一個新的答案,因爲它與之前的答案不同。 – aL3xa 2010-02-05 18:25:00
幾周前我一直在做類似的事情。這是一個可能的解決方案,它是從頭開始編寫的,所以它是一種beta版本或類似的東西。我將嘗試通過從代碼中去除循環來改善它...
主要想法是編寫一個函數,它將採用2(或3)個參數。第一個是data.frame
,它包含從問卷收集的數據,第二個是帶有正確答案的數字向量(這僅適用於單選題問卷)。或者,您可以添加第三個參數,該參數將返回帶有最終分數的數字向量或帶嵌入式分數的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)
}
我會試着用一些更加優雅的方式來做這件事,並帶有一些* ply功能。請注意,我並沒有把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。 我會嘗試修復這個...希望它有幫助!
單行:'rowSums(t(t(d)== sol),na.rm = TRUE)'。 R回收載體進行比較。如果你的'd'是矩陣的情況下,它的列簡化爲'rowSums(d == sol,na.rm = TRUE)'。 – Marek 2010-02-10 12:31:23
我剛喝了一個特別的問題,我必須指望從邏輯向量真實的陳述的數量,這個工作最適合我......
length(grep(TRUE, (gene.rep.matrix[i,1:6] > 1))) > 5
所以這需要基因的一個子集.rep.matrix對象,並應用邏輯測試,返回一個邏輯向量。這個向量作爲grep的一個參數,它返回任何TRUE條目的位置。長度然後計算grep找到的條目數,從而給出TRUE條目的數目。
另一種選擇是使用匯總功能。它給出了Ts,Fs和NAs的總結。
> summary(hival)
Mode FALSE TRUE NA's
logical 4367 53 2076
>
此外,僅獲得「TRUE」結果(將以字符串形式輸出,但在輸出中也包含「TRUE」):'summary(hival)[「TRUE」]'; – michael 2016-06-18 03:59:53
BTW,有一個好的技巧與時機在德克的回答:http://stackoverflow.com/questions/1748590/revolution-for-r/1748932#1748932 – Marek 2010-02-03 16:22:51