Посчитать количество всех слов в строке


есть ли функция для подсчета количества слов в строке? Например:

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

чтобы вернуть результат 7.

14 56

14 ответов:

можно использовать strsplit и sapply функции

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

используйте символ регулярного выражения \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

это должно выделить новую память для каждого слова, которое создается, и для промежуточного списка слов. Это может быть относительно дорого, когда данные "большие", но, вероятно, это эффективно и понятно для большинства цели.

самый простой способ будет:

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]])

The gsub(' {2,}',' ',str1) убедитесь, что все слова разделены только одним пробелом, заменив все вхождения двух или более пробелов одним пробелом.

The 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

Я использую С stringr библиотека с escape последовательность \w представляет:

любой символ "слово" (буква, цифра или подчеркивание в текущем locale: в режиме 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

попробуй такое

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

решение 7 не дает правильного результата в случае, если есть только одно слово. Вы должны не просто подсчитывать элементы в результате gregexpr (который равен -1, если там, где не соответствует), но подсчитывать элементы > 0.

Ergo:

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

использовать nchar

если вектор строк, называется x

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

узнать количество пробелов, а затем добавить один

и с stringi пакет, прямая прямая функция stri_count_words

stringi::stri_count_words(str1)
#[1] 7
require(stringr)
str_count(x,"\w+")

будет хорошо с двойными / тройными пробелами между словами

все остальные ответы на вопросы с более чем одним пробелом между словами.