web-dev-qa-db-ja.com

文字列内のすべての単語の数を数える

文字列内の単語の数を数える関数はありますか?例えば:

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

7の結果を返します。

68
John

strsplitおよびsapply関数を使用できます

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

正規表現記号_\\W_を使用して、Word以外の文字と一致させ、_+_を使用して1つ以上の行を示し、gregexprを使用して文字列内のすべての一致を検索します。単語は、単語の区切り記号に1を足した数です。

_lengths(gregexpr("\\W+", str1)) + 1
_

これは、「Word」が_\\W_の非Wordの概念を満たさない場合、文字ベクトルの先頭または末尾に空白の文字列があると失敗します(他の正規表現、_\\S+_、 _[[:alpha:]]_など。ただし、常に正規表現アプローチを使用するEdgeケースがあります。)など。各Wordにメモリを割り当てるstrsplitソリューションよりも効率的である可能性があります。正規表現は_?regex_で説明されています。

更新コメントおよび@Andriによる別の回答に記載されているように、アプローチは(ゼロ)および1ワードの文字列、および末尾の句読点で失敗します

_str1 = c("", "x", "x y", "x y!" , "x y! z")
lengths(gregexpr("[A-z]\\W+", str1)) + 1L
# [1] 2 2 2 3 3
_

他の回答の多くは、これらのケースまたは同様のケース(複数スペースなど)でも失敗します。元の答えの「1つの単語の概念」に関する私の答えの警告は句読点の問題をカバーしていると思います(解決策:_[[:space:]]+_などの別の正規表現を選択してください)が、0と1のWordケースは問題です; @Andriのソリューションは、0単語と1単語を区別できません。だから、単語を見つけるために「肯定的な」アプローチを取る

_sapply(gregexpr("[[:alpha:]]+", str1), function(x) sum(x > 0))
_

につながる

_sapply(gregexpr("[[:alpha:]]+", str1), function(x) sum(x > 0))
# [1] 0 1 2 2 3
_

繰り返しますが、正規表現は「Word」のさまざまな概念に合わせて洗練されている可能性があります。

私はgregexpr()の使用が好きです。なぜならそれはメモリ効率が良いからです。 strsplit()(@ user813966に似ていますが、単語を区切る正規表現を使用)を使用し、単語を区切る元の概念を使用する代替方法は次のとおりです。

_lengths(strsplit(str1, "\\W+"))
# [1] 0 1 2 2 3
_

これは、作成された各Wordおよび中間の単語リストに新しいメモリを割り当てる必要があります。これは、データが「大きい」場合は比較的高価になる可能性がありますが、おそらくほとんどの目的にとって効果的で理解しやすいでしょう。

67
Martin Morgan

最も簡単な方法は次のようになります。

require(stringr)
str_count("one,   two three 4,,,, 5 6", "\\S+")

...空白以外の文字(\\S+)。

しかし、どの種類のwordsを決定し、どのベクトル全体で動作します同様に?

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
40
petermeissner

stringrライブラリのstr_count関数を、次を表すエスケープシーケンス\wと共に使用します。

「Word」文字(現在のロケールの文字、数字、またはアンダースコア:UTF-8モードのみASCII文字と数字が考慮されます)

例:

> str_count("How many words are in this sentence", '\\w+')
[1] 7

私がテストできた他の9つの回答のうち、これまでにここで提示されたすべての入力に対して働いたのは(Vincent Zoonekynd、およびpetermeissnerによる)2つだけですが、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
25
arekolek
_str2 <- gsub(' {2,}',' ',str1)
length(strsplit(str2,' ')[[1]])
_

gsub(' {2,}',' ',str1)は、2つ以上のスペースのすべての出現を1つのスペースに置き換えることにより、すべての単語が1つのスペースのみで区切られるようにします。

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
_
15

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

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 
11
bartektartanus

ライブラリでwc関数を使用できますqdap

> str1 <- "How many words are in this sentence"
> wc(str1)
[1] 7
7
yuqian

二重スペースを削除し、文字列内の" "の数をカウントして、単語の数を取得できます。 ストリンガーを使用およびrm_white {qdapRegex}

str_count(rm_white(s), " ") +1
6
Murali Menon

これを試して

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

ソリューション7は、Wordが1つしかない場合に正しい結果を提供しません。 gregexprの結果の要素を数えるだけではなく(一致しない場合は-1になります)、0より大きい要素を数えます。

エルゴ:

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

stringiパッケージからも、直接的な関数stri_count_words

stringi::stri_count_words(str1)
#[1] 7
1
Sotos

require(stringr)

非常に単純な関数を定義する

str_words <- function(sentence) {

  str_count(sentence, " ") + 1

}

小切手

str_words(This is a sentence with six words)
1
JDie
require(stringr)
str_count(x,"\\w+")

単語間にダブル/トリプルスペースがあれば問題ありません

他のすべての回答には、単語間に複数のスペースがあるという問題があります。

1
CJunk

私は、次の関数と正規表現がWordカウントに役立つことを発見しました。特に、前者は一般にWordブレークとしてカウントされるべきではないシングルハイフとダブルハイフンを処理する際に役立ちます。一方、二重ハイフンは句読点の区切り文字であり、括弧で囲まれた場合など、空白で区切られていません。

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
0
Soren

ncharを使用

文字列のベクトルがxと呼ばれる場合

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

スペースの数を調べてから追加します

0
Jonny

stringrパッケージを使用すると、たとえば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
}

結果の列:stringsおよびcharacterには単語と文字のカウントが含まれ、これは文字列のベクトルに対してワンゴーで達成されます。

0
Sadiaz