एक स्ट्रिंग में सभी शब्दों की संख्या गिनें


82

क्या एक स्ट्रिंग में शब्दों की संख्या की गणना करने के लिए एक फ़ंक्शन है? उदाहरण के लिए:

str1 <- "How many words are in this sentence"

7 का परिणाम वापस करने के लिए।


नीचे दिए गए @ मार्टिन के जवाब के आधार पर मैंने एक फ़ंक्शन काउंटडेपर्सेंटेंस बनाया। जो दिए गए टेक्स्ट स्ट्रिंग में प्रति वाक्य के शब्दों की संख्या को गिनता है। कई वाक्यों वाले एक लंबे पाठ के लिए यह उन सभी में शब्दों की गणना करेगा और प्रति वाक्य शब्दों की कुल संख्या और शब्दों की कुल संख्या को आउटपुट करेगा।
पॉल रौजीक्स

1
str_count (अस्थायी $ प्रश्न 1, "") +1 आसान होगा यदि आप जानते हैं कि प्रत्येक शब्द अंतरिक्ष द्वारा अलग किए गए हैं। यह लाइब्रेरी स्ट्रिंग के तहत है।
विवेक श्रीवास्तव

जवाबों:


24

आप उपयोग strsplitऔर sapplyकार्य कर सकते हैं

sapply(strsplit(str1, " "), length)

2
बस एक अद्यतन जिसे आप अब lengthsबेस आर में कुछ नए फ़ंक्शन का उपयोग कर सकते हैं , जो प्रत्येक तत्व की लंबाई का पता लगाता है:lengths(strsplot(str, " "))
निक टियरनी

यह बहुत अच्छी समस्या है जब आपके पास "शब्द, शब्द, शब्द" जैसा कुछ होता है उस स्थिति में यह 1 वापस आ जाएगा
दिमित्रीज़ ज़ाचराटोस

71

एक पंक्ति में एक या एक से अधिक इंगित करने के लिए, एक स्ट्रिंग में सभी मैचों को खोजने के साथ \\W-साथ गैर-शब्द वर्णों का मिलान करने के लिए नियमित अभिव्यक्ति प्रतीक का उपयोग +करें gregexpr। शब्द शब्द विभाजक प्लस 1 की संख्या है।

lengths(gregexpr("\\W+", str1)) + 1

यह शुरुआत या चरित्र वेक्टर के अंत में खाली तार के साथ विफल जब एक "शब्द" संतुष्ट नहीं करता होगा \\Wकी गैर शब्द की धारणा (एक अन्य नियमित अभिव्यक्ति, के साथ काम कर सकता है \\S+, [[:alpha:]]आदि, लेकिन वहाँ हमेशा होगा एक रेगेक्स दृष्टिकोण के साथ किनारे के मामले हो), आदि यह strsplitसमाधान की तुलना में अधिक कुशल है , जो प्रत्येक शब्द के लिए मेमोरी आवंटित करेगा। में नियमित अभिव्यक्ति का वर्णन किया गया है ?regex

अपडेट जैसा कि टिप्पणियों में उल्लेख किया गया है और @Andri द्वारा एक अलग जवाब में दृष्टिकोण (शून्य) और एक-शब्द स्ट्रिंग्स के साथ विफल रहता है, और अनुगामी विराम चिह्न के साथ

str1 = c("", "x", "x y", "x y!" , "x y! z")
lengths(gregexpr("[A-z]\\W+", str1)) + 1L
# [1] 2 2 2 3 3

कई अन्य उत्तर भी इन या समान (जैसे, कई रिक्त स्थान) मामलों में विफल होते हैं। मुझे लगता है कि मूल उत्तर में 'एक शब्द की धारणा' के बारे में मेरा जवाब कैविएशन में विराम चिह्नों के साथ समस्याओं को हल करता है (समाधान: एक अलग नियमित अभिव्यक्ति चुनें, उदाहरण के लिए [[:space:]]+), लेकिन शून्य और एक शब्द मामले एक समस्या है; @ एंड्री का समाधान शून्य और एक शब्दों के बीच अंतर करने में विफल रहता है। इसलिए शब्दों को खोजने के लिए एक 'सकारात्मक' दृष्टिकोण लेना

sapply(gregexpr("[[:alpha:]]+", str1), function(x) sum(x > 0))

के लिए अग्रणी

sapply(gregexpr("[[:alpha:]]+", str1), function(x) sum(x > 0))
# [1] 0 1 2 2 3

नियमित रूप से 'शब्द' की विभिन्न धारणाओं के लिए नियमित अभिव्यक्ति को परिष्कृत किया जा सकता है।

मुझे इसका उपयोग पसंद है gregexpr()क्योंकि यह मेमोरी कुशल है। एक वैकल्पिक उपयोग strsplit()(@ user813966 की तरह, लेकिन शब्दों को परिसीमन करने के लिए एक नियमित अभिव्यक्ति के साथ) और मूल शब्दों के परिसीमन का उपयोग करना है

lengths(strsplit(str1, "\\W+"))
# [1] 0 1 2 2 3

इसके लिए प्रत्येक शब्द के लिए नई मेमोरी आवंटित करने की आवश्यकता है, और मध्यवर्ती सूची के लिए। जब डेटा 'बड़ा' होता है, तो यह अपेक्षाकृत महंगा हो सकता है, लेकिन शायद यह अधिकांश उद्देश्यों के लिए प्रभावी और समझ में आता है।


str1 <- c('s ss sss ss', "asdf asd hello this is your life!"); sapply(gregexpr("\\W+", str1), length) + 1रिटर्न 4और 8। पहला सही, दूसरा बहुत अधिक। मुझे लगता है कि यह विराम चिह्न गिन रहा है।
फ्रांसिस स्मार्ट

मुझे लगता है कि यह वाक्य के अंत में विराम चिह्न गिन रहा है। बहुत यकीन है कि आप रेगेक्स को शुरू और अंत के मैचों को अनदेखा करना चाहेंगे (क्षमा करें, इसके साथ अच्छा नहीं है या मैं इसे स्वयं ठीक करूंगा)।
फ्रांसिस स्मार्ट

sapply(gregexpr("\\W+", "word"), length) + 1रिटर्न 2
jaycode

धन्यवाद @fsmart - मुझे लगता है कि विराम चिह्न के बारे में चिंता मूल उत्तर में 'गैर-शब्द की धारणा' के बारे में अस्वीकरण द्वारा कवर की गई है। मैंने प्रतिक्रिया को अपडेट कर दिया है।
मार्टिन मॉर्गन

धन्यवाद @ संजय, 1 (या शून्य) शब्द इनपुट गिनने में असमर्थता एक समस्या है। मैंने मूल उत्तर अपडेट कर दिया है।
मार्टिन मॉर्गन

49

सबसे सरल तरीका होगा:

require(stringr)
str_count("one,   two three 4,,,, 5 6", "\\S+")

... गैर-अंतरिक्ष वर्णों ( \\S+) पर सभी दृश्यों की गिनती ।

लेकिन एक छोटे से समारोह के बारे में जो हमें यह भी तय करने देता है कि हम किस तरह के शब्दों को गिनना चाहते हैं और जो पूरे वैक्टर पर भी काम करते हैं ?

require(stringr)
nwords <- function(string, pseudo=F){
  ifelse( pseudo, 
          pattern <- "\\S+", 
          pattern <- "[[:alpha:]]+" 
        )
  str_count(string, pattern)
}

nwords("one,   two three 4,,,, 5 6")
# 3

nwords("one,   two three 4,,,, 5 6", pseudo=T)
# 6

37

मैं लाइब्रेरी str_countसे फंक्शन का उपयोग उस stringrएस्केप सीक्वेंस के साथ करता हूं \wजो प्रतिनिधित्व करता है:

किसी भी 'शब्द' अक्षर (वर्तमान स्थान में अक्षर, अंक या अंडरस्कोर: UTF-8 मोड में केवल ASCII अक्षर और अंक माने जाते हैं)

उदाहरण:

> str_count("How many words are in this sentence", '\\w+')
[1] 7

अन्य सभी 9 उत्तरों में से मैं परीक्षण करने में सक्षम था, केवल दो (विन्सेन्ट ज़ोन्किंड द्वारा, और पीटरमिसनर द्वारा) यहाँ अब तक प्रस्तुत सभी इनपुटों के लिए काम किया, लेकिन उन्हें भी आवश्यकता है stringr

लेकिन केवल यह समाधान अब तक प्रस्तुत सभी इनपुट के साथ काम करता है, जैसे कि "foo+bar+baz~spam+eggs"या साथ में इनपुट "Combien de mots sont dans cette phrase ?"

बेंचमार्क:

library(stringr)

questions <-
  c(
    "", "x", "x y", "x y!", "x y! z",
    "foo+bar+baz~spam+eggs",
    "one,   two three 4,,,, 5 6",
    "How many words are in this sentence",
    "How  many words    are in this   sentence",
    "Combien de mots sont dans cette phrase ?",
    "
    Day after day, day after day,
    We stuck, nor breath nor motion;
    "
  )

answers <- c(0, 1, 2, 2, 3, 5, 6, 7, 7, 7, 12)

score <- function(f) sum(unlist(lapply(questions, f)) == answers)

funs <-
  c(
    function(s) sapply(gregexpr("\\W+", s), length) + 1,
    function(s) sapply(gregexpr("[[:alpha:]]+", s), function(x) sum(x > 0)),
    function(s) vapply(strsplit(s, "\\W+"), length, integer(1)),
    function(s) length(strsplit(gsub(' {2,}', ' ', s), ' ')[[1]]),
    function(s) length(str_match_all(s, "\\S+")[[1]]),
    function(s) str_count(s, "\\S+"),
    function(s) sapply(gregexpr("\\W+", s), function(x) sum(x > 0)) + 1,
    function(s) length(unlist(strsplit(s," "))),
    function(s) sapply(strsplit(s, " "), length),
    function(s) str_count(s, '\\w+')
  )

unlist(lapply(funs, score))

आउटपुट:

6 10 10  8  9  9  7  6  6 11

यह दृष्टिकोण उत्कृष्ट है, लेकिन एक मुद्दा जिसका मैं अभी भी सामना कर रहा हूं वह यह है कि यह उन शब्दों को दोहराता है जिनमें एपोस्ट्रोफ होता है (उदाहरण के लिए "मैं" या "जॉन का")। क्या इसका कोई उपाय है?
थ्रेडोलसेन

2
@ थ्रेडोलेंस यदि आप सुनिश्चित हैं कि एपोस्ट्रोफ़्स नहीं होंगे जिन्हें शब्द विभाजक के रूप में माना जाना चाहिए, तो आप एक चरित्र वर्ग का उपयोग कर सकते हैं '[\\w\']+'(यह परीक्षण नहीं कर सकते हैं, इसलिए xkcd.com/1638 लागू हो सकते हैं), अन्यथा मुझे यकीन नहीं है कि अगर regex सामान्य मामले में इसे संभालने के लिए काफी शक्तिशाली है :)
arekolek

1
यकीन नहीं होता है कि यह एक अच्छी धारणा है, लेकिन अगर एपोस्ट्रोफ के बाद हमेशा एक या दो अक्षर होते हैं, तो '\\w+(\'\\w{1,2})?'एक अच्छा समाधान हो सकता है।
इस्कॉलेक

धन्यवाद। दोनों दृष्टिकोण सबसे अधिक भाग के लिए काम करते हैं, लेकिन '[\\ w \'] + 'मेरे मामले में बेहतर प्रतीत होता है, क्योंकि कुछ शब्दों में एपोस्ट्रोफ के बाद 2 से अधिक अक्षर होते हैं (उदाहरण: o'clock)। संबंधित अनुवर्ती प्रश्न: क्या उन मामलों को भी बाहर करने का कोई तरीका है जहां एक बृहदान्त्र को एक संख्यात्मक चरित्र के बाद सीधे किया जाता है (उदाहरण के लिए '10: 15' को एक शब्द के रूप में, दो के बजाय)?
थ्रेडोलसेन

2
इस टिप्पणी में मैं सादे रेगेक्स सिंटैक्स का उपयोग करने जा रहा हूं, इसलिए उदाहरणों में कुछ अतिरिक्त बैकस्लैम की आवश्यकता है। जैसे शब्दों को कवर करने के लिए o'clockऔर friggin'आप कर सकते हैं \w+('\w*)?(मुझे नहीं पता कि क्या ऐसे शब्द हैं जो एपोस्ट्रोफ से शुरू होते हैं?)। इसके अतिरिक्त घंटों को संभालने के लिए आप उनकी \d?\d:\d\d|\w+('\w*)?ज़रूरतों के आधार पर उनकी तरह मैच करने या कुछ और भी जटिल करने की कोशिश कर सकते हैं। लेकिन यह आर और के बारे में कम और अधिक है कि आप एक शब्द को कैसे परिभाषित करते हैं, इसलिए शायद आप अपनी विशिष्ट आवश्यकताओं को कवर करने के लिए एक अलग प्रश्न पोस्ट कर सकते हैं?
इस्कॉलेक

15
str2 <- gsub(' {2,}',' ',str1)
length(strsplit(str2,' ')[[1]])

यह gsub(' {2,}',' ',str1)सुनिश्चित करता है कि सभी शब्दों को एक स्थान के साथ दो या अधिक स्थानों की सभी घटनाओं को प्रतिस्थापित करके केवल एक स्थान द्वारा अलग किया जाता है।

strsplit(str,' ')हर जगह पर वाक्य विभाजन और एक सूची में परिणाम देता है। [[1]]उस सूची से बाहर शब्दों का वेक्टर पकड़ लेता है। lengthकितने शब्द ऊपर गिना जाता है।

> str1 <- "How many words are in this     sentence"
> str2 <- gsub(' {2,}',' ',str1)
> str2
[1] "How many words are in this sentence"
> strsplit(str2,' ')
[[1]]
[1] "How"      "many"     "words"    "are"      "in"       "this"     "sentence"
> strsplit(str2,' ')[[1]]
[1] "How"      "many"     "words"    "are"      "in"       "this"     "sentence"
> length(strsplit(str2,' ')[[1]])
[1] 7

टैब, नई लाइनों या गैर-अटूट स्थानों के बारे में क्या?
बार्टार्टार्टनस

एक 5yr पुराने उत्तर को पुनर्जीवित करने का तरीका! किसी भी प्रकार के व्हाट्सएप को '' के बजाय शामिल करने के लिए '\' s (R, '\\ s' में) का उपयोग करें।
mathematical.coffee

मुझे अपने उत्तर के बारे में एक सूचना मिली है और उन्हें थोड़ा सुधारने के लिए दूसरों की ओर देखा है: D पागल मत हो जाओ! :) PS। मुझे गणित और कॉफी भी पसंद है!
bartektartanus

13

आप str_match_allएक नियमित अभिव्यक्ति के साथ उपयोग कर सकते हैं , जो आपके शब्दों की पहचान करेगा। निम्नलिखित प्रारंभिक, अंतिम और दोहराए गए रिक्त स्थान के साथ काम करता है।

library(stringr)
s <-  "
  Day after day, day after day,
  We stuck, nor breath nor motion;
"
m <- str_match_all( s, "\\S+" )  # Sequences of non-spaces
length(m[[1]])

11

stringiपैकेज से इस फ़ंक्शन का प्रयास करें

   require(stringi)
   > s <- c("Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
    +        "nibh augue, suscipit a, scelerisque sed, lacinia in, mi.",
    +        "Cras vel lorem. Etiam pellentesque aliquet tellus.",
    +        "")
    > stri_stats_latex(s)
        CharsWord CharsCmdEnvir    CharsWhite         Words          Cmds        Envirs 
              133             0            30            24             0             0 

6
@bartektartanusthat कुछ अच्छी कार्यक्षमता है!
जॉन

5
धन्यवाद :) इस पैकेज से बाकी कार्यों की जाँच करें! मुझे यकीन है कि आप कुछ दिलचस्प पाएंगे :) किसी भी टिप्पणी का स्वागत किया जाता है!
बार्टार्टार्टनस

7

आप लाइब्रेरी qdap में wc फ़ंक्शन का उपयोग कर सकते हैं :

> str1 <- "How many words are in this sentence"
> wc(str1)
[1] 7

6

आप " "शब्दों की गिनती प्राप्त करने के लिए डबल स्पेस निकाल सकते हैं और स्ट्रिंग की संख्या गिन सकते हैं। स्ट्रिंग और rm_white{ qdapRegex } का उपयोग करें

str_count(rm_white(s), " ") +1


5

stringiपैकेज से भी , सीधे आगे समारोहstri_count_words

stringi::stri_count_words(str1)
#[1] 7

4

समाधान 7 केवल एक शब्द के मामले में सही परिणाम नहीं देता है। आपको केवल gregexpr के परिणाम में तत्वों की गणना नहीं करनी चाहिए (जो कि अगर मैच नहीं है तो -1 है) लेकिन तत्वों को गिनें> 0।

Ergo:

sapply(gregexpr("\\W+", str1), function(x) sum(x>0) ) + 1 

str1गैर-वर्ण वर्णों के साथ प्रारंभ या समाप्त होने पर यह अभी भी समस्या होगी । अगर यह एक चिंता का विषय है, तो यह संस्करण केवल शब्दों के बीच रिक्त स्थान की तलाश करेगा:sapply(gregexpr("\\b\\W+\\b", str, perl=TRUE), function(x) sum(x>0) ) + 1
एडम ब्रैडली

4
require(stringr)
str_count(x,"\\w+")

शब्दों के बीच डबल / ट्रिपल रिक्त स्थान के साथ ठीक हो जाएगा

अन्य सभी उत्तरों में शब्दों के बीच एक से अधिक स्थान वाले मुद्दे हैं।


2

की आवश्यकता होती है (stringr)

एक बहुत ही सरल कार्य को परिभाषित करें

str_words <- function(sentence) {

  str_count(sentence, " ") + 1

}

जाँच

str_words(This is a sentence with six words)

1

उपयोग nchar

अगर तार के सदिश को कहा जाता है x

(nchar(x) - nchar(gsub(' ','',x))) + 1

रिक्त स्थान की संख्या ज्ञात करें, फिर एक जोड़ें


1

मैंने निम्नलिखित फ़ंक्शन और रेगेक्स को शब्द गणना के लिए उपयोगी पाया है, विशेष रूप से एकल बनाम डबल हाइफ़न से निपटने में, जहां पूर्व को आमतौर पर शब्द ब्रेक, जैसे, प्रसिद्ध, हाय-फाई के रूप में नहीं गिनना चाहिए; जबकि डबल हाइफ़न एक विराम चिह्न है जो श्वेत-स्थान से घिरा नहीं है - जैसे कि पैतृक टिप्पणी के लिए।

txt <- "Don't you think e-mail is one word--and not two!" #10 words
words <- function(txt) { 
length(attributes(gregexpr("(\\w|\\w\\-\\w|\\w\\'\\w)+",txt)[[1]])$match.length) 
}

words(txt) #10 words

स्ट्रिंगि एक उपयोगी पैकेज है। लेकिन यह हाइफन के कारण इस उदाहरण में शब्दों को गिनता है।

stringi::stri_count_words(txt) #11 words

0

स्ट्रिंग पैकेज के साथ , एक सरल स्क्रिप्ट भी लिख सकता है जो लूप के माध्यम से उदाहरण के लिए तार के एक वेक्टर को पार कर सकता है।

हम कहते हैं

df $ पाठ

स्ट्रिंग्स का एक वेक्टर होता है जिसका हम विश्लेषण करने में रुचि रखते हैं। सबसे पहले, हम नीचे दिए गए मौजूदा डेटाफ्रेम df में अतिरिक्त कॉलम जोड़ते हैं:

df$strings    = as.integer(NA)
df$characters = as.integer(NA)

फिर हम नीचे दिए गए तारों के वेक्टर पर एक लूप चलाते हैं:

for (i in 1:nrow(df)) 
{
   df$strings[i]    = str_count(df$text[i], '\\S+') # counts the strings
   df$characters[i] = str_count(df$text[i])         # counts the characters & spaces
}

परिणामी कॉलम: स्ट्रिंग्स और कैरेक्टर में शब्दों और वर्णों की गिनती शामिल होगी और यह स्ट्रिंग के वेक्टर के लिए वन-गो में प्राप्त किया जाएगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.