문자열의 모든 단어 수를 센다


82

문자열의 단어 수를 세는 기능이 있습니까? 예를 들면 :

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

7의 결과를 반환합니다.


아래 @Martin 의 답변 에 따라 주어진 텍스트 문자열에서 문장 당 단어 수를 계산하는 countwordpersentence.R 함수를 만들었습니다 . 여러 문장이 포함 된 긴 텍스트의 경우 모든 단어를 세어 문장 당 평균 단어 수와 총 단어 수를 출력합니다.
Paul Rougieux 2015 년

1
str_count (temp $ question1, "") +1은 각 단어가 공백으로 구분되어 있다는 것을 알고 있으면 쉬울 것입니다. 라이브러리 스트링 러 아래에 있습니다.
Vivek Srivastava

답변:


22

당신은 사용할 수 있습니다 strsplitsapply기능

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

이제 lengths각 요소의 길이를 찾는 기본 R에서 다소 새로운 기능을 사용할 수있는 업데이트입니다 .lengths(strsplot(str, " "))
Nick Tierney

이것은 당신이 1 리턴이 경우에 "단어, 단어, 단어"같은 때 문제가 매우 좋다
드미트리 Zacharatos

71

정규식 기호 \\W를 사용하여 비 단어 문자를 일치시키고을 사용하여 +행에서 하나 이상을 표시 gregexpr하고 문자열에서 모든 일치 항목을 찾습니다. 단어는 단어 구분자 수에 1을 더한 것입니다.

lengths(gregexpr("\\W+", str1)) + 1

는 "단어가"만족하지 않는 경우이 시작 또는 문자 벡터의 끝에서 빈 문자열과 실패 \\W의 '비 단어의 개념을 (하나는 다른 정규 표현식으로 일할 수 \\S+, [[:alpha:]]등,하지만 거기에 항상 것입니다 정규식 접근 방식을 사용하는 경우) 등이 strsplit있습니다. 각 단어에 메모리를 할당하는 솔루션 보다 더 효율적일 수 있습니다. 정규식은에 설명되어 ?regex있습니다.

업데이트 주석 및 @Andri의 다른 답변에서 언급했듯이 접근 방식은 (0) 및 한 단어 문자열과 후행 구두점으로 실패합니다.

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

다른 많은 답변도 이러한 또는 유사한 경우 (예 : 여러 공백)에서 실패합니다. 원래 답변에서 '한 단어의 개념'에 대한 내 답변의 경고는 구두점 문제를 다루고 있다고 생각합니다 (솔루션 : 다른 정규 표현식 선택, 예 [[:space:]]+), 0 및 1 단어 대소 문자 가 문제입니다. @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

다시 정규식은 '단어'의 다른 개념에 대해 정제 될 수 있습니다.

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반환 48. 첫 번째는 맞고 두 번째는 너무 많습니다. 구두점을 세는 것 같아요.
Francis Smart

문장 끝의 구두점을 세는 것 같아요. 정규식에 시작 및 종료 일치를 무시하도록 지시하고 싶을 것입니다 (미안하지만 좋지 않거나 직접 고칠 것입니다).
Francis Smart

sapply(gregexpr("\\W+", "word"), length) + 12 반환
jaycode

감사합니다 @fsmart-구두점에 대한 우려는 원래 답변의 '단어가 아닌 개념'에 대한 면책 ​​조항으로 덮여 있다고 생각합니다. 응답을 업데이트했습니다.
Martin Morgan

@jaycode에게 감사합니다. 1 개 (또는 0 개) 단어 입력을 계산할 수 없다는 것이 문제입니다. 원래 답변을 업데이트했습니다.
Martin Morgan

47

가장 간단한 방법 은 다음과 같습니다.

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

35

다음 을 나타내는 이스케이프 시퀀스와 함께 라이브러리 의 str_count함수를 사용합니다 .stringr\w

모든 '단어'문자 (현재 로케일의 문자, 숫자 또는 밑줄 : UTF-8 모드에서는 ASCII 문자와 숫자 만 고려 됨)

예:

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

내가 테스트 할 수있는 다른 9 개의 답변 중 2 개 (Vincent Zoonekynd 및 petermeissner 작성)만이 지금까지 여기에 제시된 모든 입력에 대해 작동했지만 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

이 접근 방식은 훌륭하지만 여전히 접하는 한 가지 문제는 아포스트로피 (예 : "I 'm"또는 "John 's")가 포함 된 단어를 이중 계산한다는 것입니다. 이 문제를 해결할 방법이 있습니까?
Thredolsen

2
@Thredolsen 단어 구분 기호로 취급해야하는 아포스트로피가 없을 것이라고 확신하는 경우 문자 클래스를 사용할 수 있습니다 '[\\w\']+'(테스트 할 수 없으므로 xkcd.com/1638 이 적용될 수 있음). 그렇지 않으면 확실하지 않습니다. 정규식은 일반적인 경우를 처리 할 수있을만큼 강력합니다. :)
arekolek

1
그것이 좋은 가정인지 확실하지 않지만, 아포스트로피 뒤에 항상 한두 글자 만 있다면 '\\w+(\'\\w{1,2})?'좋은 해결책이 될 수 있습니다.
arekolek 19 년

감사합니다. 두 방법 모두 대부분 작동하지만 '[\\ w \'] + '가 더 나은 것 같습니다. 일부 단어는 아포스트로피 뒤에 2 자 이상을 포함하기 때문입니다 (예 : o'clock). 관련 후속 질문 : 콜론 뒤에 숫자가 직접 오는 경우도 제외 할 수있는 방법이 있습니까 (예 : '10 : 15 '를 두 단어가 아닌 한 단어로 계산)?
Thredolsen

2
이 주석에서는 일반 정규식 구문을 사용하므로 예제에는 추가 백 슬래시가 필요합니다. 같은 단어를 포함하는 방법 o'clockfriggin'당신이 할 수있는 \w+('\w*)?(아포스트로피로 시작하는 단어가 있는지 모르겠어요?). 시간을 추가로 처리하려면 \d?\d:\d\d|\w+('\w*)?필요에 따라 원하는대로 맞추 거나 더 복잡한 작업을 수행 할 수 있습니다. 그러나 이것은 R에 대한 것보다 단어를 정의하는 방법에 관한 것이므로 특정 요구를 충족시키기 위해 별도의 질문을 게시 할 수 있습니까?
arekolek

15
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

탭, 새 줄 또는 깨지지 않는 공백은 어떻습니까?
bartektartanus

5 년 된 답변을 부활시키는 방법! ''가 아닌 모든 유형의 공백을 포함하려면 '\ s'(R에서 '\\ s')를 사용하십시오.
mathematical.coffee

내 답변에 대한 알림을 받았으며 다른 사람들을 살펴보고 약간 개선했습니다. : D 화 내지 마세요! :) 추신. 나도 수학과 커피를 좋아해요!
bartektartanus

13

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

11

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 

6
@bartektartanus 좋은 기능입니다!
John

5
감사합니다 :)이 패키지의 나머지 기능을 확인하십시오! 흥미로운 것을 찾을 수있을 거라고 확신합니다. :) 모든 의견을 환영합니다!
bartektartanus

7

라이브러리 qdap 에서 wc 함수를 사용할 수 있습니다 .

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

6

이중 공백을 제거 " "하고 문자열의 수를 계산하여 단어 수를 얻을 수 있습니다. stringrrm_white{ qdapRegex } 사용

str_count(rm_white(s), " ") +1


5

또한 stringi패키지에서 바로 앞으로 기능stri_count_words

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

4

해 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
아담 브래들리

4
require(stringr)
str_count(x,"\\w+")

단어 사이에 이중 / 삼중 공백이 있으면 괜찮습니다.

다른 모든 답변에는 단어 사이에 둘 이상의 공백이있는 문제가 있습니다.


2

필요 (스트링 러)

매우 간단한 함수 정의

str_words <- function(sentence) {

  str_count(sentence, " ") + 1

}

검사

str_words(This is a sentence with six words)

1

사용하다 nchar

문자열 벡터가 호출되면 x

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

공간 수를 확인한 다음 하나 추가


1

다음 함수와 정규식이 단어 수, 특히 단일 하이픈 대 이중 하이픈 처리에 유용하다는 것을 발견했습니다. 전자는 일반적으로 잘 알려진 하이파이와 같이 단어 분리로 계산되지 않아야합니다. 이중 하이픈은 괄호 주석과 같이 공백으로 묶이지 않는 구두점 구분 기호입니다.

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

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
}

결과 열 : 문자열문자 는 단어와 문자의 수를 포함하며 이는 문자열 벡터에 대해 한 번만 수행됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.