Mantıksal bir vektörde TRUE değerleri nasıl sayılır


160

R'de, TRUEmantıksal bir vektördeki değer sayısını saymanın en etkili / deyimsel yolu nedir? İki şekilde düşünebilirim:

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

table(z)["TRUE"]
# TRUE 
#  498 

Hangisini tercih edersin? Daha iyi bir şey var mı?

Yanıtlar:


174

Mantıksal vektör NAdeğer içerdiğinde bazı sorunlar vardır .
Örneğin bakınız:

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)

Bu yüzden en güvenli olanı kullanmak olduğunu düşünüyorum na.rm = TRUE:

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

(1 verir). tableÇözümün daha az verimli olduğunu düşünüyorum ( tablefonksiyon koduna bakın ).

Ayrıca, mantıksal vektörde DOĞRU değer olmaması durumunda "tablo" çözümüne dikkat etmelisiniz. Diyelim z <- c(NA, FALSE, NA)ya da basitçe z <- c(FALSE, FALSE), her iki durum için de table(z)["TRUE"]size verir NA.


table(c(FALSE))["TRUE"]NA değil 0 verir.
Yossi Farjoun

@YossiFarjoun Evet ve bu benim cevabımda. Bu neden işe yaramıyor. Benim çözümümsum(z, na.rm = TRUE)
Marek

84

Bahsedilmeyen bir başka seçenek de which:

length(which(z))

Sadece "daha hızlı soru" hakkında bir bağlam sağlamak için, kendinizi test etmek her zaman en kolay yoldur. Vektörü karşılaştırma için çok daha büyük yaptım:

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 

Bu durumda açıkça kullanmak sumen iyi yaklaşımdır. NAMarek'un önerdiği gibi değerleri kontrol etmek de isteyebilirsiniz .

Sadece NA değerleri ve whichfonksiyonuyla ilgili bir not eklemek için :

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

Sadece mantıksal olup olmadığını kontrol eder TRUE, bu yüzden aslında mantıksal olmayan değerleri yok sayar.


BTW, Dirk cevabında zamanlama ile güzel bir hile vardı: stackoverflow.com/questions/1748590/revolution-for-r/…
Marek

12

Başka bir yol

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

sum(z) Güzel ve kısa olsa da, benim length(z[z==TRUE])için daha fazla kendini açıklıyor. Yine de, böyle basit bir görevle gerçekten bir fark yaratmadığını düşünüyorum ...

Büyük bir vektörse, muhtemelen en hızlı çözümle gitmelisiniz, yani sum(z). length(z[z==TRUE])yaklaşık 10 kat daha yavaş ve table(z)[TRUE]yaklaşık 200 kat daha yavaştır sum(z).

Özetlemek sum(z), yazmak ve uygulamak en hızlı olandır.


6

whichözellikle matrisler üzerinde çalışırken iyi bir alternatiftir ( argümanı kontrol edin ?whichve dikkat edin arr.ind). Ama mantıklı vektörde işleyebilecek argüman sumyüzünden hareket etmenizi öneririm . Örneğin:na.rmNA

# 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

Yazarsanız sum(x)size alırsınız NAbunun sonucunda ancak geçmek eğer na.rm = TRUEiçinde sumişlevi, istediğiniz bu sonucu elde edersiniz.

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

Sorunuz kesinlikle teorik mi yoksa mantıksal vektörlerle ilgili bazı pratik sorunlarınız mı var?


Bir sınav not almaya çalışıyordum. Bir uygulama içinde toplam (youranswer == rightanswer) gibi bir şey yapmak.
Jyotirmoy Bhattacharya

Cevabım çok uzun, bu yüzden öncekinden farklı olduğu için yeni bir cevap gönderdim.
aL3xa

6

Başka bir seçenek de özet işlevini kullanmaktır. Ts, Fs ve NA'ların bir özetini verir.

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

1
Ayrıca, yalnızca "TRUE" sonuçlarını elde etmek için (dize olarak çıktılanacak, ancak çıktıda "TRUE" içeren) summary(hival)["TRUE"]:;
michael

0

Birkaç hafta önce benzer bir şey yapıyordum. İşte olası bir çözüm, sıfırdan yazıldı, bu yüzden bir tür beta sürümü veya bunun gibi bir şey. Koddan döngüler kaldırarak onu geliştirmeye çalışacağım ...

Ana fikir, 2 (veya 3) argüman alacak bir işlev yazmaktır. Birincisi data.frame, anketten toplanan verileri tutan ve ikincisi doğru cevapları olan sayısal bir vektördür (bu sadece tek seçenekli anket için geçerlidir). Alternatif olarak, son vektör ile sayısal vektör döndürecek üçüncü argüman veya gömülü puan ile data.frame ekleyebilirsiniz.

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)
}

Bunu bazı * kat fonksiyonları ile daha zarif bir şekilde yapmaya çalışacağım. Ben koymadığını Bildirimi na.rmargüman ... böyle yapar

# 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))

Şimdi bir işlev uygulayın:

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

Data.frame bağımsız değişkenini iletirseniz, değiştirilen data.frame döndürülür. Bunu düzeltmeye çalışacağım ... Umarım yardımcı olur!


6
Tek astarlı rowSums(t(t(d)==sol), na.rm=TRUE). Karşılaştırma için R geri dönüşüm vektörü. Eğer dsütunlarda vakaları ile matris olsaydı o zaman basitleştirir rowSums(d==sol, na.rm=TRUE).
Marek

0

Ben sadece mantıklı bir vektör gerçek ifadelerin sayısını saymak zorunda kaldı ve bu benim için en iyi çalıştı belirli bir sorun yaşadım ...

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

Yani bu, gene.rep.matrix nesnesinin bir alt kümesini alır ve mantıksal bir vektör döndürerek mantıksal bir test uygular. Bu vektör, DOĞRU girdilerin konumlarını döndüren grep'e bir argüman olarak konur. Uzunluk daha sonra grep'in kaç giriş bulduğunu hesaplar ve böylece DOĞRU giriş sayısını verir.


0

Ayrıca bithızlı boole işlemleri için özel olarak tasarlanmış bir paket de var . Özellikle büyük vektörleriniz varsa veya birçok boolean işlemi yapmanız gerektiğinde kullanışlıdır.

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
})
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.