Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Count the number of all words in a string

Is there a function to count the number of words in a string? For example:

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

to return a result of 7.

like image 810
John Avatar asked Jan 19 '12 01:01

John


People also ask

How do you count words in a string in Python?

Use the count() Method to Count Words in Python String Python. The count() method is a Python built-in method. It takes three parameters and returns the number of occurrences based on the given substring.

How do you count the number of words in a list?

Using the count() Function The "standard" way (no external libraries) to get the count of word occurrences in a list is by using the list object's count() function. The count() method is a built-in function that takes an element as its only argument and returns the number of times that element appears in the list.


2 Answers

Use the regular expression symbol \\W to match non-word characters, using + to indicate one or more in a row, along with gregexpr to find all matches in a string. Words are the number of word separators plus 1.

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

This will fail with blank strings at the beginning or end of the character vector, when a "word" doesn't satisfy \\W's notion of non-word (one could work with other regular expressions, \\S+, [[:alpha:]], etc., but there will always be edge cases with a regex approach), etc. It is likely more efficient than strsplit solutions, which will allocate memory for each word. Regular expressions are described in ?regex.

Update As noted in the comments and in a different answer by @Andri the approach fails with (zero) and one-word strings, and with trailing punctuation

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

Many of the other answers also fail in these or similar (e.g., multiple spaces) cases. I think my answer's caveat about 'notion of one word' in the original answer covers problems with punctuation (solution: choose a different regular expression, e.g., [[:space:]]+), but the zero and one word cases are a problem; @Andri's solution fails to distinguish between zero and one words. So taking a 'positive' approach to finding words one might

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

Leading to

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

Again the regular expression might be refined for different notions of 'word'.

I like the use of gregexpr() because it's memory efficient. An alternative using strsplit() (like @user813966, but with a regular expression to delimit words) and making use of the original notion of delimiting words is

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

This needs to allocate new memory for each word that is created, and for the intermediate list-of-words. This could be relatively expensive when the data is 'big', but probably it's effective and understandable for most purposes.

like image 139
Martin Morgan Avatar answered Oct 02 '22 01:10

Martin Morgan


Most simple way would be:

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

... counting all sequences on non-space characters (\\S+).

But what about a little function that lets us also decide which kind of words we would like to count and which works on whole vectors as well?

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 
like image 45
petermeissner Avatar answered Oct 02 '22 01:10

petermeissner