이번에 우리가 예제로 사용할 dataset은 USArrests라는 미국 각 주의 범죄율에 관련한 데이터입니다. 물론 우리는 text processing에 관심이 있기 때문에 주의 이름만을 참조할 예정입니다 :) 간단하게 dataset이 어떻게 생겼는지 확인해 봅시다.

head(USArrests)
##            Murder Assault UrbanPop Rape
## Alabama      13.2     236       58 21.2
## Alaska       10.0     263       48 44.5
## Arizona       8.1     294       80 31.0
## Arkansas      8.8     190       50 19.5
## California    9.0     276       91 40.6
## Colorado      7.9     204       78 38.7

각 행이 하나의 주라는 것을 알 수 있죠? 각 행의 이름이 주의 이름이기 때문에 rownames함수를 사용해 이들을 vector형태로 가지고 오겠습니다.

states=rownames(USArrests) # 주의 이름이 각 행의 이름이므로 rownames함수를 사용하여 가지고 옵니다.
head(states)
## [1] "Alabama"    "Alaska"     "Arizona"    "Arkansas"   "California"
## [6] "Colorado"

그런데 주 이름이 너무 기네요. 이들을 네 글자로 축약하고 싶으면 어떻게 해야 할까요? 가장 간단하게 생각할 수 있는 방법은 첫 네글자만 추출하는 방법입니다. 이것은 substr함수를 통해 간단하게 할 수 있습니다.

substr(x=states, start=1, stop=4) #substr함수는 string vector의 element하나 당 적용되는 함수입니다. R은 index가 1부터 시작한다는 것을 유념하세요!
##  [1] "Alab" "Alas" "Ariz" "Arka" "Cali" "Colo" "Conn" "Dela" "Flor" "Geor"
## [11] "Hawa" "Idah" "Illi" "Indi" "Iowa" "Kans" "Kent" "Loui" "Main" "Mary"
## [21] "Mass" "Mich" "Minn" "Miss" "Miss" "Mont" "Nebr" "Neva" "New " "New "
## [31] "New " "New " "Nort" "Nort" "Ohio" "Okla" "Oreg" "Penn" "Rhod" "Sout"
## [41] "Sout" "Tenn" "Texa" "Utah" "Verm" "Virg" "Wash" "West" "Wisc" "Wyom"

그런데 이렇게 앞의 네글자만 뽑아내다보니, ‘New ‘와 같은 동일한 이름의 주들이 생겨서 알아보기가 어렵겠죠? R에서는 간단하면서도 강력한 abbreviate함수를 통해서 멋지게 축약할 수 있습니다.

states2=abbreviate(states)
head(states2)
##    Alabama     Alaska    Arizona   Arkansas California   Colorado 
##     "Albm"     "Alsk"     "Arzn"     "Arkn"     "Clfr"     "Clrd"

그런데 단순한 vector형태가 아닌 이렇게 각 element당 이름이 붙어서 보기 힘들게 되어있죠? 이렇게 붙어있는 이름들을 제거해 줍시다.

names(states2)=NULL #이렇게 각 element당 이름을 제거함으로써 깔끔한 vector형태로 출력이 가능합니다.
head(states2)
## [1] "Albm" "Alsk" "Arzn" "Arkn" "Clfr" "Clrd"

하지만 만약 네글자가 아닌, 다섯글자 내지는 다른 글자수로 줄이고 싶다면 어떻게 해야 할까요? abbreviate함수에는 minlength라는 parameter가 있습니다. 이를 설정함으로써 가능합니다.

abbreviate(states, minlength = 5) #minlength를 통해서 몇글자로 줄일것인지 설정할 수 있습니다.
##        Alabama         Alaska        Arizona       Arkansas     California 
##        "Alabm"        "Alask"        "Arizn"        "Arkns"        "Clfrn" 
##       Colorado    Connecticut       Delaware        Florida        Georgia 
##        "Colrd"        "Cnnct"        "Delwr"        "Flord"        "Georg" 
##         Hawaii          Idaho       Illinois        Indiana           Iowa 
##        "Hawai"        "Idaho"        "Illns"        "Indin"         "Iowa" 
##         Kansas       Kentucky      Louisiana          Maine       Maryland 
##        "Kanss"        "Kntck"        "Lousn"        "Maine"        "Mryln" 
##  Massachusetts       Michigan      Minnesota    Mississippi       Missouri 
##        "Mssch"        "Mchgn"        "Mnnst"        "Mssss"        "Missr" 
##        Montana       Nebraska         Nevada  New Hampshire     New Jersey 
##        "Montn"        "Nbrsk"        "Nevad"        "NwHmp"        "NwJrs" 
##     New Mexico       New York North Carolina   North Dakota           Ohio 
##        "NwMxc"        "NwYrk"        "NrthC"        "NrthD"         "Ohio" 
##       Oklahoma         Oregon   Pennsylvania   Rhode Island South Carolina 
##        "Oklhm"        "Oregn"        "Pnnsy"        "RhdIs"        "SthCr" 
##   South Dakota      Tennessee          Texas           Utah        Vermont 
##        "SthDk"        "Tnnss"        "Texas"         "Utah"        "Vrmnt" 
##       Virginia     Washington  West Virginia      Wisconsin        Wyoming 
##        "Virgn"        "Wshng"        "WstVr"        "Wscns"        "Wymng"

그렇다면, 각 string들의 길이를 알고 싶을 땐 어떻게 해야할까요? 이를 해결해 주는 함수가 nchar함수입니다.

state_chars = nchar(states)
head(state_chars)
## [1]  7  6  7  8 10  8

그렇다면 가장 긴 주의 이름은 어떤 것일까요? 다음의 명령어는 가장 긴 주의 이름에 해당하는 index에서 True값을 갖는 boolean vector를 리턴합니다. which함수를 통해 True값을 갖는 element의 index를 추출한 후 subset을 찾으면 결국 가장 긴 주의 이름을 얻게 됩니다.

state_chars == max(state_chars) #이렇게 논리연산자는 boolean vector를 리턴합니다.
##  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [12] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [23] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE
## [34] FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE
## [45] FALSE FALSE FALSE FALSE FALSE FALSE
which(state_chars == max(state_chars)) #which 함수를 통해서 해당 vector에서 true값의 index를 리턴합니다.
## [1] 33 40
states[which(state_chars == max(state_chars))] #해당 index로 가장 긴 이름의 주를 확인할 수 있죠.
## [1] "North Carolina" "South Carolina"

그럼 우리가 원하는 패턴을 string vector에서 찾아내고 싶으면 어떻게 해야 할까요? 이런 유용한 기능을 하는 함수가 grep입니다. 만약 주의 이름에 ‘k’가 들어가는 것들만 찾아내고 싶다고 가정해 봅시다.

grep(pattern = 'k', x = states, value = F) #value=F는 해당 index들을 리턴합니다.
## [1]  2  4 17 27 32 34 36 41
grep(pattern = 'k', x = states, value = T) #value=T는 해당 element들을 리턴합니다.
## [1] "Alaska"       "Arkansas"     "Kentucky"     "Nebraska"    
## [5] "New York"     "North Dakota" "Oklahoma"     "South Dakota"

위와 같이 쉽게 찾을 수 있네요. 그럼 만약에 w나 W, 두 가지 패턴에 대해 동시에 검사해보고 싶으면 어떻게 할까요? pattern에 square bracket으로 문자들을 감싸주면 됩니다. 간단하죠?

grep(pattern = '[wW]', x = states, value = T)
##  [1] "Delaware"      "Hawaii"        "Iowa"          "New Hampshire"
##  [5] "New Jersey"    "New Mexico"    "New York"      "Washington"   
##  [9] "West Virginia" "Wisconsin"     "Wyoming"

이 방법 말고도, states이름 자체를 모두 소문자로 변환한다면 w만 가지고도 체크가 가능할 것입니다.

#tolower함수를 통해 string vector를 모두 소문자로 변환합니다.
grep(pattern = 'w', x = tolower(states), value = T)
##  [1] "delaware"      "hawaii"        "iowa"          "new hampshire"
##  [5] "new jersey"    "new mexico"    "new york"      "washington"   
##  [9] "west virginia" "wisconsin"     "wyoming"

반대로 toupper를 사용하면 모두 대문자가 되겠죠?

grep(pattern = 'W', x = toupper(states), value = T)
##  [1] "DELAWARE"      "HAWAII"        "IOWA"          "NEW HAMPSHIRE"
##  [5] "NEW JERSEY"    "NEW MEXICO"    "NEW YORK"      "WASHINGTON"   
##  [9] "WEST VIRGINIA" "WISCONSIN"     "WYOMING"

마지막 방법은 grep함수의 ignore.caseTrue로 설정해주는 것입니다.

grep(pattern = 'w', x = states, value = T, ignore.case = T)
##  [1] "Delaware"      "Hawaii"        "Iowa"          "New Hampshire"
##  [5] "New Jersey"    "New Mexico"    "New York"      "Washington"   
##  [9] "West Virginia" "Wisconsin"     "Wyoming"

일단 기본적인 R을 이용한 text processing 기법들을 알아보았습니다. 물론 아주 일부분이지만 하나씩 알아나가서 이것들을 이용해 text mining을 해 나가니 필히 잘 익혀두시면 좋을 것 같습니다 :)