R TRUE
で、論理ベクトルの値の数を数える最も効率的/慣用的な方法は何ですか?私は2つの方法を考えることができます:
z <- sample(c(TRUE, FALSE), 1000, rep = TRUE)
sum(z)
# [1] 498
table(z)["TRUE"]
# TRUE
# 498
どっちがいい?さらに良いものはありますか?
R TRUE
で、論理ベクトルの値の数を数える最も効率的/慣用的な方法は何ですか?私は2つの方法を考えることができます:
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)
だから私は最も安全だと思いますna.rm = TRUE
:
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"]
あなたNA
を与えます。
sum(z, na.rm = TRUE)
言及されていない別のオプションは使用することwhich
です:
length(which(z))
「これはより速い質問です」に関するコンテキストを実際に提供するためだけに、自分でテストすることは常に最も簡単です。比較のためにベクトルを大きくしました:
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
、この場合、明らかに使用することが最善の方法です。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
、結果として、しかし、あなたが渡す場合na.rm = TRUE
にはsum
機能、あなたが望むという結果が得られます。
> sum(x)
[1] NA
> sum(x, na.rm=TRUE)
[1] 43
あなたの質問は厳密に理論的なものですか、それとも論理ベクトルに関する実際的な問題がありますか?
私は数週間前に同じようなことをしてきました。考えられる解決策は次のとおりです。ゼロから作成されているため、ベータ版などのようなものです。私はコードからループを削除することでそれを改善しようとします...
主なアイデアは、2つ(または3つ)の引数を取る関数を記述することです。1つ目は、data.frame
アンケートから収集したデータを保持するa で、2つ目は、正解の数値ベクトルです(これは、単一選択アンケートにのみ適用されます)。または、最終スコアを含む数値ベクトル、またはスコアが埋め込まれたdata.frameを返す3番目の引数を追加できます。
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)
。
私は論理ベクトルから真のステートメントの数を数えなければならないという特定の問題を抱えていましたが、これが私にとって最もうまくいきました...
length(grep(TRUE, (gene.rep.matrix[i,1:6] > 1))) > 5
したがって、これはgene.rep.matrixオブジェクトのサブセットを受け取り、論理テストを適用して論理ベクトルを返します。このベクトルは、任意のTRUEエントリの場所を返すgrepへの引数として配置されます。次に、Lengthは、grepが検出したエントリの数を計算し、TRUEエントリの数を示します。
bit
高速ブール演算用に特別に設計されたというパッケージもあります。これは、ベクトルが大きい場合や、多数のブール演算を実行する必要がある場合に特に便利です。
z <- sample(c(TRUE, FALSE), 1e8, rep = TRUE)
system.time({
sum(z) # 0.170s
})
system.time({
bit::sum.bit(z) # 0.021s, ~10x improvement in speed
})
table(c(FALSE))["TRUE"]
NAではなく0を与える