计算字符串中所有单词的数量

问题描述 投票:67回答:17

是否有一个函数来计算字符串中的单词数?例如:

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

返回7的结果。

r string word-count
17个回答
14
投票

您可以使用strsplitsapply函数

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

5
投票

试试这个

length(unlist(strsplit(str1," ")))

4
投票

在只有一个单词的情况下,解7没有给出正确的结果。你不应该只计算gregexpr结果中的元素(如果不匹配则为-1),但计算元素> 0。

因此:

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

1
投票

也来自stringi包,直线功能stri_count_words

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

1
投票
require(stringr)
str_count(x,"\\w+")

单词之间的双/三空格会很好

所有其他答案都有问题,单词之间有多个空格。


1
投票

需要(stringr)

定义一个非常简单的功能

str_words <- function(sentence) {

  str_count(sentence, " ") + 1

}

校验

str_words(This is a sentence with six words)

0
投票

使用nchar

如果字符串的矢量被称为x

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

找出空格数然后添加一个


0
投票

使用stringr包,还可以编写一个简单的脚本,该脚本可以遍历字符串向量,例如通过for循环。

让我们说吧

DF $文本

包含我们有兴趣分析的字符串向量。首先,我们在现有数据框df中添加其他列,如下所示:

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

然后我们在字符串向量上运行for循环,如下所示:

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
}

结果列:字符串和字符将包含单词和字符的计数,这将一次性实现字符串向量。


0
投票

我发现以下函数和正则表达式对单词计数有用,特别是在处理单连词和双连字符时,前者通常不应算作单词中断,例如,众所周知的高保真音响;而双连字符是一个不受空格限制的标点符号分隔符 - 例如括号内的空格。

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是一个有用的包。但是由于连字符,它在这个例子中过多地计算了单词。

stringi::stri_count_words(txt) #11 words

66
投票

使用正则表达式符号\\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:]]+),但零和一个单词的情况是个问题; @Andri的解决方案无法区分零和一个单词。因此,采取“积极”的方法来寻找一个可能的话

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

这需要为每个创建的单词和中间单词列表分配新的内存。当数据“很大”时,这可能相对昂贵,但对于大多数目的而言,这可能是有效且可理解的。


40
投票

最简单的方法是:

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

25
投票

我使用str_count库中的stringr函数和转义序列\w代表:

任何'word'字符(当前语言环境中的字母,数字或下划线:在UTF-8模式下,只考虑ASCII字母和数字)

例:

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

在我能够测试的所有其他9个答案中,只有两个(由Vincent Zoonekynd和petermeissner)为目前为止所提供的所有输入工作,但他们也需要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

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

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 

7
投票

你可以在库qdap中使用wc函数:

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

6
投票

您可以删除双空格并计算字符串中" "的数量以获取单词的计数。使用stringr和rm_white {qdapRegex}

str_count(rm_white(s), " ") +1
© www.soinside.com 2019 - 2024. All rights reserved.