तार्किक वेक्टर में TRUE मानों की गणना कैसे करें


160

आर में, TRUEएक तार्किक वेक्टर में मूल्यों की संख्या की गणना करने के लिए सबसे कुशल / मुहावरेदार तरीका क्या है ? मैं दो तरह से सोच सकता हूं:

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

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

आप क्या पसंद करेंगे? क्या कुछ बेहतर भी है?

जवाबों:


174

जब तार्किक वेक्टर में 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दोनों मामलों के लिए देता है ।


table(c(FALSE))["TRUE"]NA देता है, न कि 0.
योसी फरजून

@YossiFarjoun हां, और यह मेरे जवाब में है। यह उदाहरण है कि यह काम क्यों नहीं करेगा। मेरे sollution हैsum(z, na.rm = TRUE)
मारेक

84

एक अन्य विकल्प जिसका उल्लेख नहीं किया गया है, वह है 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मूल्यों के लिए भी जांच कर सकते हैं जैसा कि मर्क ने सुझाव दिया है।

बस एनए मूल्यों और whichसमारोह के बारे में एक नोट जोड़ने के लिए :

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

ध्यान दें कि जो केवल तार्किक के लिए जांच करता है TRUE, इसलिए यह अनिवार्य रूप से गैर-तार्किक मूल्यों की अनदेखी करता है।


BTW, डिर्क उत्तर में समय के साथ एक अच्छी चाल थी: stackoverflow.com/questions/1748590/revolution-for-r/…
Marek

12

दूसरा तरीका है

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

जबकि sum(z) अच्छा और छोटा है, मेरे length(z[z==TRUE])लिए अधिक आत्म व्याख्या है। हालांकि, मुझे लगता है कि इस तरह एक साधारण कार्य के साथ यह वास्तव में कोई फर्क नहीं पड़ता ...

यदि यह एक बड़ा वेक्टर है, तो आपको संभवतः सबसे तेज़ समाधान के साथ जाना चाहिए, जो कि है sum(z)length(z[z==TRUE])के बारे में 10x धीमी है और table(z)[TRUE]की तुलना में लगभग 200x धीमी है sum(z)

सममिंग, sum(z)टाइप करने और निष्पादित करने के लिए सबसे तेज़ है।


6

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

क्या आपका प्रश्न कड़ाई से सैद्धांतिक है, या आपके पास तार्किक वैक्टर के संबंध में कुछ व्यावहारिक समस्या है?


मैं एक प्रश्नोत्तरी ग्रेड करने की कोशिश कर रहा था। एक आवेदन के भीतर राशि (आपका शेयर == राइट शेयर) जैसा कुछ करना।
ज्योतिर्मय भट्टाचार्य

मेरा उत्तर अभी बहुत लंबा है, इसलिए मैंने एक नया उत्तर पोस्ट किया है, क्योंकि यह पिछले एक से अलग है।
एएल

6

एक अन्य विकल्प सारांश फ़ंक्शन का उपयोग करना है। यह Ts, Fs और NA का सारांश देता है।

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

1
इसके अलावा, केवल "TRUE" परिणाम प्राप्त करने के लिए (जो एक स्ट्रिंग के रूप उत्पादन किया जाएगा, लेकिन यह भी शामिल है "TRUE" उत्पादन में): summary(hival)["TRUE"];
माइकल

0

मैं कुछ हफ्ते पहले भी ऐसा ही कर रहा हूं। यहां एक संभावित समाधान है, यह खरोंच से लिखा गया है, इसलिए यह बीटा-रिलीज़ या ऐसा कुछ है। मैं कोड से छोरों को हटाकर इसे बेहतर बनाने की कोशिश करूंगा ...

मुख्य विचार एक फ़ंक्शन लिखना है जो 2 (या 3) तर्क लेगा। पहला वह है 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

यदि आप डेटा.फ़्रेम तर्क पास करते हैं, तो यह संशोधित डेटा.फ़्रेम लौटाएगा। मैं इसे ठीक करने की कोशिश करूँगा ... आशा है कि यह मदद करता है!


6
वन-लाइनर rowSums(t(t(d)==sol), na.rm=TRUE):। तुलना के लिए पुनरावर्तन वेक्टर। यदि आपके dकॉलम में मामलों के साथ मैट्रिक्स थे, तो इसका सरलीकरण होता है rowSums(d==sol, na.rm=TRUE)
मारेक

0

मेरे पास एक विशेष समस्या है जहां मुझे एक तार्किक वेक्टर से सही बयानों की संख्या की गणना करनी थी और यह मेरे लिए सबसे अच्छा काम करता है ...

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

इसलिए यह जीन.rep.matrix ऑब्जेक्ट का सबसेट लेता है, और लॉजिकल वेक्टर को लौटाकर लॉजिकल टेस्ट लागू करता है। इस वेक्टर को grep के तर्क के रूप में रखा गया है, जो किसी भी TRUE प्रविष्टियों के स्थानों को लौटाता है। लंबाई तब गणना करती है कि कितने प्रविष्टियाँ grep ढूँढती हैं, इस प्रकार TRUE प्रविष्टियों की संख्या दे रही है।


0

वहाँ एक पैकेज भी कहा जाता 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
})
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.