Есть ли функция для подсчета количества слов в строке? Например:
str1 <- "How many words are in this sentence"
чтобы вернуть результат 7.
Есть ли функция для подсчета количества слов в строке? Например:
str1 <- "How many words are in this sentence"
чтобы вернуть результат 7.
Вы можете использовать функции strsplit
и sapply
sapply(strsplit(str1, " "), length)
lengths
в базе R, которая определяет длину каждого элемента: lengths(strsplot(str, " "))
- person Nick Tierney; 13.05.2019
Используйте символ регулярного выражения \\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
. Первое правильно, второе - слишком много. Я думаю, это счет знаков препинания.
- person Francis Smart; 15.05.2015
sapply(gregexpr("\\W+", "word"), length) + 1
возвращает 2
- person jaycode; 16.05.2015
Самый простой способ:
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
с 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 ?"
.
Контрольный показатель:
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 может применяться), иначе я не уверен, достаточно ли мощное регулярное выражение, чтобы справиться с этим в общем случае :)
- person arekolek; 26.03.2019
'\\w+(\'\\w{1,2})?'
может быть хорошим решением.
- person arekolek; 26.03.2019
o'clock
и friggin'
, вы можете использовать \w+('\w*)?
(я не знаю, есть ли слова, начинающиеся с апострофа?). Чтобы дополнительно обрабатывать часы, вы можете попытаться сопоставить их, например, \d?\d:\d\d|\w+('\w*)?
, или сделать что-то еще более сложное в зависимости от ваших потребностей. Но это все меньше и меньше о R и больше о том, как вы определяете слово, так что, может быть, вы можете опубликовать отдельный вопрос, чтобы охватить свои конкретные потребности?
- person arekolek; 27.03.2019
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
Вы можете использовать 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
Попробуй это
length(unlist(strsplit(str1," ")))
Также из пакета stringi
прямая функция stri_count_words
stringi::stri_count_words(str1)
#[1] 7
Решение 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
- person Adam Bradley; 01.07.2013
require(stringr)
str_count(x,"\\w+")
будет нормально с двойными / тройными пробелами между словами
Во всех других ответах есть проблемы с более чем одним пробелом между словами.
требовать (строка)
Определите очень простую функцию
str_words <- function(sentence) {
str_count(sentence, " ") + 1
}
Проверять
str_words(This is a sentence with six words)
Используйте 1_
если вектор строк называется x
(nchar(x) - nchar(gsub(' ','',x))) + 1
Узнайте количество пробелов и добавьте один
Я нашел следующую функцию и регулярное выражение, полезные для подсчета слов, особенно при работе с одинарными и двойными дефисами, где первый обычно не должен считаться разрывом слова, например, хорошо известный, привет-Fi; тогда как двойной дефис - это разделитель знаков препинания, который не ограничен пробелом, например, для замечаний в скобках.
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
С помощью пакета 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
}
Результирующие столбцы: строки и символ будут содержать количество слов и символов, и это будет достигнуто за один раз для вектора строк.