有功能来计算字符串中的单词数吗?例如:
str1 <- "How many words are in this sentence"
返回结果7。
有功能来计算字符串中的单词数吗?例如:
str1 <- "How many words are in this sentence"
返回结果7。
Answers:
您可以使用strsplit
和sapply
功能
sapply(strsplit(str1, " "), length)
lengths
基础R中的某些新功能来查找每个元素的长度:lengths(strsplot(str, " "))
使用正则表达式符号\\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
这需要为创建的每个单词以及中间单词列表分配新的内存。当数据“大”时,这可能会相对昂贵,但对于大多数用途而言,它可能是有效且易于理解的。
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
最简单的方法是:
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
我str_count
将stringr
库中的函数与\w
表示以下内容的转义序列一起使用:
任何“单词”字符(在当前语言环境中为字母,数字或下划线:在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
'[\\w\']+'
(无法测试,因此可能适用xkcd.com/1638),否则我不确定是否regex功能强大,足以应付一般情况:)
'\\w+(\'\\w{1,2})?'
可能是一个好的解决方案。
o'clock
,friggin'
您就可以做到\w+('\w*)?
(我不知道是否有以撇号开头的单词?)。要另外处理几个小时,您可以尝试根据需要匹配它们,\d?\d:\d\d|\w+('\w*)?
或者做一些更复杂的事情。但这与R的关系越来越少,而与如何定义单词的关系也越来越多,因此也许您可以发布一个单独的问题来满足您的特定需求?
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
从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不会给出正确的结果。您不应该只计算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
我发现以下函数和正则表达式可用于字数统计,尤其是在处理单连字符和双连字符时,前者通常不应算作断字,例如,众所周知的高保真;而双连字符是不受空格限制的标点分隔符,例如用于括号的注释。
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
带纵梁包,还可以编写一个简单的脚本,该脚本可以遍历字符串的向量,例如通过for循环。
比方说
df $ text
包含一个我们感兴趣的字符串向量。首先,我们向现有数据框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
}
产生的列:字符串和字符将包含单词和字符的计数,并且对于字符串向量将一次性完成。