Посчитать количество всех слов в строке
есть ли функция для подсчета количества слов в строке? Например:
str1 <- "How many words are in this sentence"
для возврата результата 7.
14 ответов
используйте символ регулярного выражения \W
чтобы соответствовать символам без слов, используя +
чтобы указать один или несколько в строке, наряду с gregexpr
найти все совпадения в строке. Слова-это количество разделителей слов плюс 1.
lengths(gregexpr("\W+", str1)) + 1
это не удастся с пустыми строками в начале или конце символьного вектора, когда "слово" не удовлетворяет \W
понятие не-слова (можно работать с другими регулярными выражениями,\S+
, [[:alpha:]]
, etc., но будет всегда быть крайними случаями с подходом regex) и т. д. Это, вероятно, более эффективно, чем 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
для этого необходимо выделить новую память для каждого созданного слова и для промежуточного списка слов. Это может быть относительно дорого, когда данные "большие", но, вероятно, это эффективно и понятно для большинства цели.
самый простой способ будет:
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
str2 <- gsub(' {2,}',' ',str1)
length(strsplit(str2,' ')[[1]])
на gsub(' {2,}',' ',str1)
удостоверяется, что все слова разделены только одним пробелом, заменяя все случаи двух или более пробелов одним пробелом.
на strsplit(str,' ')
разбивает предложение на каждый пробел и возвращает результат в списке. The [[1]]
захватывает вектор слов из этого списка. The 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
Я использую С stringr
библиотека с escape последовательность \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 ?"
.
Benchmark:
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
можно использовать 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]])
попробуйте эту функцию из 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
можно использовать wc в библиотеке qdap:
> str1 <- "How many words are in this sentence"
> wc(str1)
[1] 7
вы можете удалить двойные пробелы и подсчитать количество " "
в строке, чтобы получить количество слов. использовать stringr и rm_white
{qdapRegex}
str_count(rm_white(s), " ") +1
решение 7 не дает правильного результата в случае, если есть только одно слово. Вы должны не просто подсчитать элементы в результате gregexpr (который равен -1, если там, где не совпадает), но подсчитать элементы > 0.
Ergo:
sapply(gregexpr("\W+", str1), function(x) sum(x>0) ) + 1
использовать nchar
если вектор строк, называется x
(nchar(x) - nchar(gsub(' ','',x))) + 1
узнайте количество пробелов, а затем добавьте один
require(stringr)
str_count(x,"\w+")
будет хорошо с двойными / тройными пробелами между словами
все остальные ответы на вопросы с более чем одним пробелом между словами.