1. 텍스트 처리 함수

1.1 기본 함수

1.1.1 nchar()

  • 문자의 수를 세어준다
nchar("한국")
## [1] 2
nchar(c("Korea", "한국"))
## [1] 5 2

1.1.2 length()

  • 원소의 수를 세어준다
length("한국")
## [1] 1
length(c("한국", "Korea"))
## [1] 2

1.1.3 substr()

  • 문자열을 추출
substr("BigDataAnalysis", start = 4, stop = 4)
## [1] "D"
substr("BigDataAnalysis", 4, 7)
## [1] "Data"
country <- c("Korea", "Japan", "China", "Singapole", "Russia")
substr(country, start = 1, stop = 3)
## [1] "Kor" "Jap" "Chi" "Sin" "Rus"
  • 문자열 추가
  • 시작 위치 지정, 끝 위치 지정(시작 위치 + 글자수) -1
myword <- "This is the Big Data Analysis"
x <- strsplit(myword, split = "")
x <- strsplit(myword, split = "a")
x

substr(myword,x[1], x[1] + attr(x, 'match.length') -1)

1.1.4 strsplit()

  • 하나의 문장을 일정한 기준에 따라 분리해준다
myword <- "This is the Big Data Analysis"
x <- strsplit(myword, split = "")
x <- strsplit(myword, split = "a")
x
## [[1]]
## [1] "This is the Big D" "t"                 " An"              
## [4] "lysis"
class(x)
## [1] "list"
  • 여러 문장을 분리할 경우, 문장 별로 리스트 원소에 저장
myword1 <- "This is the Big Data Analysis 1"
myword2 <- "This is the Big Data Analysis 2"
myword3 <- "This is the Big Data Analysis 3"
myword <- c(myword1, myword2, myword3)

for(i in myword)
  result <- strsplit(myword, split = " ")

result
## [[1]]
## [1] "This"     "is"       "the"      "Big"      "Data"     "Analysis"
## [7] "1"       
## 
## [[2]]
## [1] "This"     "is"       "the"      "Big"      "Data"     "Analysis"
## [7] "2"       
## 
## [[3]]
## [1] "This"     "is"       "the"      "Big"      "Data"     "Analysis"
## [7] "3"
  • 마침표, 쉼표, 괄호 등으로 분리할 때는 2개의 백슬래시(\)와 함께 사용한다.
myword <- "저의 꿈은 빅데이터 분석가입니다. 훌륭한 빅데이터 분석가입니다."
strsplit(myword, split = "\\.")
## [[1]]
## [1] "저의 꿈은 빅데이터 분석가입니다" " 훌륭한 빅데이터 분석가입니다"

1.1.5 paste()

  • 문자열을 붙여주는 기능을 한다.
number <- 1:10
alphabet <- c("a", "b", "c")
paste(number, alphabet)
##  [1] "1 a"  "2 b"  "3 c"  "4 a"  "5 b"  "6 c"  "7 a"  "8 b"  "9 c"  "10 a"
paste(number, alphabet, sep = " ")
##  [1] "1 a"  "2 b"  "3 c"  "4 a"  "5 b"  "6 c"  "7 a"  "8 b"  "9 c"  "10 a"
paste(number, alphabet, sep = ",")
##  [1] "1,a"  "2,b"  "3,c"  "4,a"  "5,b"  "6,c"  "7,a"  "8,b"  "9,c"  "10,a"
  • collapse 옵션을 사용하면 벡터 원소들을 하나로 합칠 수도 있다.
paste(number, collapse = "")
## [1] "12345678910"
paste(alphabet, collapse = "")
## [1] "abc"
  • 리스트로 된 위의 결과도 다시 합칠 수 있다.
for(i in 1:length(result))
  print(paste(result[[i]], collapse = " "))
## [1] "This is the Big Data Analysis 1"
## [1] "This is the Big Data Analysis 2"
## [1] "This is the Big Data Analysis 3"

1.1.6 regexpr()

  • 이 함수는 지정된 표현이 텍스트에 등장하는지, 등장한다면 나타나는 첫 위치가 어디인지 알려준다.
  • 없다면 -1 이 출력된다.
myword <- "저의 꿈은 빅데이터 분석가입니다. 훌륭한 빅데이터 분석가입니다."
x <- regexpr('입니다', myword)
x
## [1] 15
## attr(,"match.length")
## [1] 3

1.1.7 gregexpr()

  • 지정된 표현을 텍스트 전체에서 찾아주는 함수
myword <- "저의 꿈은 빅데이터 분석가입니다. 훌륭한 빅데이터 분석가입니다."
x <- gregexpr('입니다', myword)
  • 결과가 리스트로 되어 있다.
x[[1]]
## [1] 15 32
## attr(,"match.length")
## [1] 3 3
attr(x[[1]], 'match.length')
## [1] 3 3
  • 둘 이상의 원소에서 찾으려면 다음과 같다
x <- gregexpr('입니다', myword)
x[[2]]
attr(x[[2]], 'match.length')

1.1.8 grep()

  • 특정 표현이 나타나는 원소의 번호를 알려준다.
myword <- "저의 꿈은 빅데이터 분석가입니다. 훌륭한 빅데이터 분석가입니다."
grep('입니다', myword)
## [1] 1
grep('우리', myword)
## integer(0)
grep('우리', myword, value = TRUE)
## character(0)

1.1.9 grepl()

  • 나타나는지 여부를 T/F로 알려준다.
  • value = TRUE 옵션을 사용할 수 없다.
grepl('입니다', myword)
## [1] TRUE

1.1.10 sub(), gsud()

  • sub() 함수는 처음 등장하는 지정된 표현을 다른 지정된 표현으로 바꾼다.
  • gsub()은 모든 등장하는 지정된 표현을 다른 지정된 표현으로 바꾼다.
  • gsub()은 모든 공백 문자와 함께 사용하면 지정된 표현을 삭제하는 효과를 갖는다.
myword <- "저의 꿈은 빅데이터 분석가입니다. 훌륭한 빅데이터 분석가입니다."
sub('입니다', '일까요', myword)
## [1] "저의 꿈은 빅데이터 분석가일까요. 훌륭한 빅데이터 분석가입니다."
gsub('입니다', '일까요', myword)
## [1] "저의 꿈은 빅데이터 분석가일까요. 훌륭한 빅데이터 분석가일까요."

1.1.11 regmathces()

  • 지정된 표현을 추출한다.
  • substr 함수와 비슷하나, 위치가 아니라, 표현을 입력한다.
  • regexpr(), gregexpr() 함수와 같이 사용된다.
myword <- "저의 꿈은 빅데이터 분석가입니다. 훌륭한 빅데이터 분석가입니다."
mypattern <- gregexpr("입니다", myword)
regmatches(myword, mypattern)
## [[1]]
## [1] "입니다" "입니다"

1.2 정규표현식

  • 일정한 패턴을 갖는 문자열을 바복적으로 찾을 때는 정규표현식을 사용하는 것이 좋다.
  • 정규표현식은 낯선 기호로 되어 있어서 처음에는 다루기가 익숙하지 않지만, 일종의 프로그래밍 기능을 갖고 있으므로 생산성이 매우 높아진다.
  • 보통 gregexpr(), regmathces를 엮어서 사용한다

1.2.1 숫자와 문자

[:digit:] : 숫자로 표시된 텍스트 [:lower:] : 소문자 알파벳으로 [:upper:] : 대문자 알파벳으로 [:alpha:] : 문자로 표시된 [:alnum:] : 숫자와 문자로 표시된

1.2.2 기호류

[:punct:] : 구두점으로 표시된 텍스트 [:graph:] : 가시적으로 표현된 텍스트 [:alnum:] + [:punct:][:blank:] : 스페이스나 태븡ㄹ 이용하여 공란으로 표현된 텍스트 [:space:] : 스페이스, 탭, 줄바꿈 등을 이용해 공란으로 표현된 텍스트 [:print:] : 출력했을 때 확인할 수 있는 텍스트 [:cntrl:] : “, , ” 와 같은 제어문자

1.2.3 양화기호

? : 선행표현을 고려할 수도, 고려하지 않을 수도 있으며 최대 1회 매칭됨 * : 선행표현이 0회 혹은 그 이상 매칭됨 + : 선행표현이 1회 혹은 그 이상 매칭됨 {n} : 선행표현이 정확하게 n 회 매칭 {n,} : 선행표현이 n회 이상 매칭 {n, m} : 선행표현이 n회 이상, m회 미만으로 매칭

1.2.4 사용된 표현 추출

myword <- c("1번째는 사랑입니다", "2번째는 우정입니다. 3번째는 같이")
mypattern <- gregexpr("[[:digit:]]", myword)
regmatches(myword, mypattern)
## [[1]]
## [1] "1"
## 
## [[2]]
## [1] "2" "3"

1.2.5 특정 표현과의 연결

myword  <- c("1번째는 사랑입니다", "2번째는 가족입니다")
mypattern <- gregexpr("[[:digit:]](번째)", myword)
regmatches(myword, mypattern)
## [[1]]
## [1] "1번째"
## 
## [[2]]
## [1] "2번째"

1.2.6 n회 이상의 문자 조건

myword  <- c("1번째는 사랑입니다", "2번째는 가족입니다")
mypattern <- gregexpr("[[:alpha:]] + (니다)", myword)
regmatches(myword, mypattern)
## [[1]]
## character(0)
## 
## [[2]]
## character(0)
  • 다음도 같은 결과를 산출
mypattern <- gregexpr("[[:alpha:]]{1,}(니다)", myword)
regmatches(myword, mypattern)
## [[1]]
## [1] "사랑입니다"
## 
## [[2]]
## [1] "가족입니다"

1.2.7 제한 조건

mypattern <- gregexpr("[[:alpha:]]{1,}(니다)\\b", myword)
regmatches(myword, mypattern)
## [[1]]
## [1] "사랑입니다"
## 
## [[2]]
## [1] "가족입니다"

1.2.8 빈도조사

  • unlist와 table() 함수를 사용하여 빈도조사까지 할 수 있다.
myword  <- c("1번째는 사랑입니다", "2번째는 가족입니다", "3번째도 사랑입니다")
mypattern <- gregexpr("[[:alpha:]]{1,}(니다)", myword)
x <- regmatches(myword, mypattern)
table(unlist(x))
## 
## 가족입니다 사랑입니다 
##          1          2

연습문제

NS <- readLines("C:/Rcrawl/naver_sport.txt")
mypattern <- gregexpr("[[:alpha:]]{1,}(골)",NS)
x <- regmatches(NS, mypattern)
table(unlist(x))
## < table of extent 0 >

1.3 stringr 패키지

  • stringr 패키지는 정규표현식을 비롯한 기본 함수 대부분을 다음과 같이 보다 직관적이고 효율적으로 처리할 수 있게 한다
myword <- c("1번째는 사랑입니다", "2번째는 가족입니다")
mypattern <- gregexpr("입니다", myword)
regmatches(myword, mypattern)
## [[1]]
## [1] "입니다"
## 
## [[2]]
## [1] "입니다"
  • 위와 동일한 결과를 갖는다.
library(stringr)
## Warning: package 'stringr' was built under R version 3.5.1
str_extract_all(myword, "입니다")
## [[1]]
## [1] "입니다"
## 
## [[2]]
## [1] "입니다"

1.3.1 str_locate(text, key)

  • str_locate() 및 str_locate_all() 함수는 지정된 표현을 추출한다.
  • regexpr() 및 gregexpr() 함수와 유사하다.
myword <- c("1번째는 사랑입니다. 1-2번째는 우정입니다.", "2번째는 가족입니다.")
str_locate(myword, "입니다")
##      start end
## [1,]     8  10
## [2,]     8  10
str_locate_all(myword, "입니다")
## [[1]]
##      start end
## [1,]     8  10
## [2,]    22  24
## 
## [[2]]
##      start end
## [1,]     8  10

1.3.2 str_extract, str_extract_all

  • 정규표현식도 지원한다.
myword <- c("1번째는 사랑입니다. 1-2번째는 우정입니다.", "2번째는 가족입니다.")
str_locate_all(myword, "[[:alpha:]]{1,}(니다)")
## [[1]]
##      start end
## [1,]     6  10
## [2,]    20  24
## 
## [[2]]
##      start end
## [1,]     6  10

1.3.3 str_extract(text, key)

  • str_extract() 및 str_extract_all() 함수는 지정된 표현을 추출한다.
  • simplify = TRUE 옵션을 사용하면 결과를 리스트가 아닌 행렬로 추출한다.
myword <- c("1번째는 사랑입니다. 1-2번째는 우정입니다.", "2번째는 가족입니다.")
str_extract_all(myword, "입니다", simplify = TRUE)
##      [,1]     [,2]    
## [1,] "입니다" "입니다"
## [2,] "입니다" ""

-정규표현식도 지원한다.

str_extract_all(myword, "[[:alpha:]]{1,}(니다)", simplify = TRUE)
##      [,1]         [,2]        
## [1,] "사랑입니다" "우정입니다"
## [2,] "가족입니다" ""

1.3.4 str_detect()

  • str_detect() 함수는 지정된 표현이 포함되어 있는지를 알려준다.
myword <- c("1번째는 사랑입니다. 1-2번째는 우정입니다.", "2번째는 가족입니다.")
str_detect(myword, "입니다")
## [1] TRUE TRUE

1.3.5 str_replace(text, key_old, key_new)

-str_replace 및 str_raplace_all() 함수는 지정된 표현으로 문자를 바꿔준다.

myword <- c("1번째는 사랑입니다. 1-2번째는 우정입니다.", "2번째는 가족입니다.")
str_replace(myword, "입니다", "일까요")
## [1] "1번째는 사랑일까요. 1-2번째는 우정입니다."
## [2] "2번째는 가족일까요."

1.3.6 str_split(text, key)

  • str_split() 함수는 지정된 표현으로 텍스트를 분할한다.
myword <- c("1번째는 사랑입니다. 1-2번째는 우정입니다.", "2번째는 가족입니다.")
str_split(myword, "\\.")
## [[1]]
## [1] "1번째는 사랑입니다"    " 1-2번째는 우정입니다" ""                     
## 
## [[2]]
## [1] "2번째는 가족입니다" ""

1.3.7 str_count(text, key)

  • str_count 함수는 지정된 표현이 몇 회 나타났는지를 알려준다
  • 기본 함수에는 비슷한 기능을 가진 것이 없다
myword <- c("1번째는 사랑입니다. 1-2번째는 우정입니다.", "2번째는 가족입니다.")
str_count(myword, "입니다")
## [1] 2 1

1.3.8 str_sub(text, start, stop)

  • str_sub() 함수는 문자열을 추출한다
str_sub(myword, 1, 4)
## [1] "1번째는" "2번째는"

1.3.9 str_length(text)

  • 문자의 수를 계산한다.
str_length(myword)
## [1] 25 11

1.3.10 str_c(text, sep), str_c(text, collapse)

  • str_c 함수는 벡터를 연결한다.
number <- 1:3
alphabet <- c("a", "b", "c")
str_c(number, alphabet, sep = "")
## [1] "1a" "2b" "3c"
str_c(number, alphabet, collapse = "")
## [1] "1a2b3c"

연습문제

  • stringr 함수를 이용하여 정규표현식의 연습문제와 동일한 작업을 수행
str_count(NS, "골")
## [1] 0
str_extract_all(NS, "골", simplify = F)
## [[1]]
## character(0)
x <- str_extract_all(NS, "[[:alpha:]]{1,}(골)", simplify = F)