Чи існує функція для підрахунку кількості слів у рядку? Наприклад:
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, " "))
Використовуйте символ регулярного виразу \\W
для відповідності несловним символам, використовуючи +
для позначення одного або декількох підряд, а також gregexpr
для пошуку всіх збігів у рядку. Слова - це кількість роздільників слів плюс 1.
lengths(gregexpr("\\W+", str1)) + 1
Це буде терпіти невдачі з порожніми рядками на початку або в кінці вектора символів, коли «слово» не задовольняє \\W
«s поняття несловообразующего (один може працювати з іншими регулярними виразами \\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 відповідей, які мені вдалося протестувати, лише дві (від Вінсента Зонекінда та петермайснера) працювали на всі вкладені тут матеріали, але вони також вимагають 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 ), інакше я не впевнений, що регулярний вираз є достатньо потужним, щоб впоратись із ним загалом :)
'\\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
Ви можете використовувати 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
Ви можете видалити подвійні пробіли і підрахувати кількість " "
у рядку, щоб отримати кількість слів. Використовуйте stringr та rm_white
{ qdapRegex }
str_count(rm_white(s), " ") +1
Рішення 7 не дає правильного результату, якщо є лише одне слово. Вам слід не просто підрахувати елементи в результаті gregexpr (а це -1, якщо там, де не збігається), а підрахувати елементи> 0.
Ерго:
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
Я знайшов наступну функцію та регулярний вираз корисними для підрахунку слів, особливо при роботі з одинарними та подвійними дефісами, де перші, як правило, не повинні вважатися розривом слів, наприклад, добре відомий, hi-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
}
Отримані стовпці: рядки та символ будуть містити кількість слів та символів, і це буде досягнуто одним рухом для вектора рядків.