티스토리 뷰

반응형

문자열 함수 - Stringr 패키지


 stringr 패키지는 문자열 데이터를 가공하기 위해 자주 사용되는 유용한 패키지입니다.

문자열 치환, 벡터 연산, 함수의 결과를 반복문없이 저장해주는 등 편리한 함수들을 가지고 있습니다.


install.packages("stringr")

library(stringr)




 1. str_detect() 함수


 str_detect() 함수원소별 패턴 검사를 위해 사용됩니다. 오라클의 like 연산자와 유사하죠.


str_detect(대상, 패턴)   # 대소구분. 논리값으로 리턴


> v1 <- c('aa', 'ba', 'ccb', 'Ab', 'Bbc')

> str_detect(v1,'a')

[1]  TRUE  TRUE FALSE FALSE FALSE

> v1[c(T,T,F,F,F)]                     # boolean 벡터. 원소에 논리값을 매칭시켜서 true인 값만 색인하므로 데이터 추출에도 유용합니다.  

[1] "aa" "ba"                             # 원소 순서대로 boolean값이 전달

> emp[ c(T,F,F,...) , c(T,F,F,...) ]         # data frame 의 경우 행, 열 범위에 다 사용 가능합니다.


* 정규식 표현 

v1[str_detect(v1,'a')]           # 순서 상관없이 'a'를 포함하는 원소 출력
str_detect(v1,'^a')              #  'a' 로 시작하는 원소 (^는 시작의 의미)
v1[str_detect(v1,'^a')]         # 'a' 로 시작하는 원소 출력
v1[str_detect(v1,'^[aA]')]     # 대소 상관 없이 'a' 로 시작하는 원소 출력
                                         [aA] : a or A (문자열 표현식에서의 []는 하나의 글자 패턴의 완성)

v1[str_detect(v1,'^[aAbB]')]  # 대소 상관 없이 'a' 혹은 'b' 로 시작하는 원소 출력
v1[str_detect(v1,'^[aA][bB]')] # 대소 상관 없이 a로 시작, 두 번째가 b.

                                           []는 하나의 글자를 의미. ^[][] 는 두 글자로 시작하는 원소를 의미
str_detect(v1,'a$')                # 'a' 로 끝나는 원소 ($는 끝의 의미)
v1[str_detect(v1,'a$')]           # 'a' 로 끝나는 원소 출력.


# emp 에서 이름이 s로 시작하는 직원의 정보 출력

> emp[str_detect(emp$ENAME, '^[sS]'),]

     ENAME     JOB  MGR        HIREDATE  SAL COMM DEPTNO comm2 AVG_SAL

7369 SMITH   CLERK 7902 1980-12-17 0:00  800   NA     20   100    2175

7788 SCOTT ANALYST 7566 1987-04-17 0:00 3000   NA     20   100    2175




 2. str_count() 함수


 str_count() 함수특정 문자의 출현 횟수 카운트를 위해 사용됩니다. 


> v1

[1] "aa"  "ba"  "ccb" "Ab"  "Bbc"

> str_count(v1.ignore.case('a'))    # 대소문자 구별 없이 카운트. 현재 사용 불가 (사용 될 때도 있고, 안 될 때도 있고..)

Error in v1.ignore.case("a") : could not find function "v1.ignore.case"

> str_count(v1,'a')                     # 대소문자 구별

[1] 2 1 0 0 0




3. str_c() 함수


 str_c() 함수는 문자열 결합을 위해 사용됩니다. 


> str_c('cute','dog')
[1] "cutedog"
> v1
[1] "aa"  "ba"  "ccb" "Ab"  "Bbc"
> str_c('vector: ', v1)           # 키 벨류 형태로 결합
[1] "vector: aa"  "vector: ba"  "vector: ccb" "vector: Ab"  "vector: Bbc"
> str_c(v1,' name is ',v1)      # 연결연산자를 사용하여 결합
[1] "aa name is aa"   "ba name is ba"   "ccb name is ccb" "Ab name is Ab"   "Bbc name is Bbc"
> str_c(v1, collapse="-")      # 구분 기호를 사용하면 벡터의 원소끼리 결합 
[1] "aa-ba-ccb-Ab-Bbc"

# 결합 함수의 주의점 !!!

> v1 <- c('a','b','c')

> str_c('a','b','c')    # 함수 내에 분리된 인자들을 연결

[1] "abc"

> str_c(v1)  # 여러개의 값이 들어있는 하나의 인자를 연결하기 때문에 옵션이 필요

[1] "a" "b" "c"


> str_c('a','b','c', sep = ',')  # 분리된 인자들을 연결

[1] "a,b,c"

> str_c(v1, collapse = ',')

[1] "a,b,c"




4. str_dup() 함수

 str_dup() 함수는 원소마다 반복 출력을 위해 사용됩니다. 


> v1
[1] "aa"  "ba"  "ccb" "Ab"  "Bbc"

> str_dup(v1, 3)

[1] "aaaaaa"    "bababa"    "ccbccbccb" "AbAbAb"    "BbcBbcBbc"




5. str_length() 함수

 str_length() 함수는 문자열의 길이, 벡터의 각 원소의 길이 확인을 위해 사용됩니다. 


> str_length('hello')
[1] 5
> v1
[1] "aa"  "ba"  "ccb" "Ab"  "Bbc"
> str_length(v1)
[1] 2 2 3 2 3



6. str_locate() 함수

 str_locate() 함수는 특정 문자와 매칭하는 문자열의 시작(끝) 위치 확인을 위해 사용됩니다. 


> str_locate('abab','a')         # 첫 번째 'a'의 위치, 시작 위치와 끝 위치가 같음
     start end
[1,]     1   1
> str_locate('aabab','a')       # 첫 번째 'a'의 위치, 시작 위치와 끝 위치가 같음
     start end
[1,]     1   1
> str_locate('abaab','aa')     # 첫 번째 'aa'의 위치
     start end                         특정 문자를 두 개 이상 구성 시 문자열의 시작 위치와 끝 위치가 다름(두 글자 이므로)
[1,]     3   4
> class(str_locate('abaab','aa'))   # 함수의 결과가 매트릭스 구조로 출력되는 것을 확인
[1] "matrix"

> v1
[1] "aa"  "ba"  "ccb" "Ab"  "Bbc"
> str_locate(v1,'a')                  # 벡터의 각 원소별 확인도 가능
     start end
[1,]     1   1
[2,]     2   2
[3,]    NA  NA
[4,]    NA  NA
[5,]    NA  NA




7. str_locate_all() 함수


 str_locate_all() 함수는 특정 문자와 매칭하는 문자열의 모든 위치 확인을 위해 사용됩니다. 


> v3 <- c('a','aba','b','ababab')
> v3
[1] "a"      "aba"    "b"      "ababab"
> str_locate_all(v3,'a')          
[[1]]              # 첫 번째 원소
     start end
[1,]     1   1

[[2]]              # 두 번째 원소
     start end
[1,]     1   1
[2,]     3   3

[[3]]              # 세 번째 원소
     start end

[[4]]              # 네 번째 원소
     start end
[1,]     1   1
[2,]     3   3
[3,]     5   5
> class(str_locate_all(v3,'a'))    # 함수의 결과가 리스트 구조로 출력되는 것을 확인
[1] "list"
> str_locate_all(v3,'a')[[2]][2,1]   # 함수의 결과를 리스트로 접근할 수 있습니다. 
start                                         두 번째 원소의 두 번째 a의 위치
    3 

> v3 <- c('a)','ab)a','b)','aba)bab')
> v3
[1] "a)"      "ab)a"    "b)"      "aba)bab"
> str_locate(v3,'\\)')             # 그냥 괄호는 문법으로 인식하므로, 특수기호가 아니라는 \\ 기호를 사용해주어야합니다.
     start end
[1,]     2   2
[2,]     3   3
[3,]     2   2
[4,]     4   4



8. str_replace() 함수  중요!


 str_replace() 함수는 (처음으로 매칭하는 값만의)문자의 치환과 삭제에 자주 사용됩니다. 굉장히 많이 사용된다고 하니 중요!

 str_replace_all() 함수는 (매칭하는 모든 값의)문자의 치환과 삭제에 자주 사용


> str_replace('apple','p','*')         # 처음으로 매칭하는 값만 치환 

[1] "a*ple"

> str_replace('apple','p','**')

[1] "a**ple"

> str_replace_all('apple','p','*')     # 매칭하는 모든 값을 치환 

[1] "a**le"

> v4 <- c('1,100', '2,300', '3,900')  # 1000 단위 구분기호, (,)컴마 때문에 문자로 인식하겠죠? 

> v4 + 100  # 문자와 숫자는 연산 불가 !

Error in v4 + 100 : non-numeric argument to binary operator

> v4 <- str_replace(v4,',','')         (,)컴마 제거  

> as.numeric(v4) + 100              숫자형으로 변환 후 연산

[1] 1200 2400 4000


> v4 <- c('1,100,200', '1,002,300', '1,003,900')      (,)컴마가 두 개 이상이라면, 그냥 replace() 함수는 모두 치환이 불가하답니다.

> v4 <- str_replace_all(v4,',','')                            # 그렇기 때문에 이럴 때는 이왕이면 replace_all() 함수를 사용하는게 좋겠죠? 

> as.numeric(v4) + 100

[1] 1100300 1002400 1004000




9. str_split() 함수 


 str_split() 함수는 기호를 기준으로 문자열을 분리하기 위해 사용됩니다. 결과는 리스트 형식으로 리턴됩니다.


> animal <- str_c('pig', '/', 'dog', '/', 'cat')

> animal

[1] "pig/dog/cat"

> str_split(animal, '/')       # '/' 기호를 기준으로 분리

[[1]]                               # 리스트 형식의 결과

[1] "pig" "dog" "cat"





10. str_sub() 함수 


 str_sub() 함수는 문자열에서 원하는 문자(데이터)만 추출하기 위해 사용됩니다. 인자는 위치(주소) 기반

오라클과 다소 헷갈리므로 이해를 잘 해두어야 합니다.
오라클에서 3번째 인자 end는 문자의 개수를 의미하지만, R에서 end는 문자의 위치를 적어줘야합니다.

> animal

[1] "pig/dog/cat"

> str_sub(animal, start = 1, end = 3)

[1] "pig"

> str_sub(animal, start = 5, end = 7)

[1] "dog"

> str_sub(animal, start = 5)       # end 생략 시 끝까지 추출

[1] "dog/cat"

> str_sub(animal, start = -4)     # 음수 기입 시, 뒤에서부터 n번째 위치를 기준으로 start

[1] "/cat"




11. str_trim() 함수 


 str_trim() 함수는 공백 제거 용도로 사용됩니다. 

공백 제거 방향은 옵션으로 설정할 수 있고, 중간 공백은 삭제가 되지 않습니다. (중간 공백 치환을 위해서는 replace() 함수를 사용)


> str_trim(' pig dog cat ')

[1] "pig dog cat"                  # 양 쪽 공백 제거

> str_trim(' pig dog cat ', side = 'left')

[1] "pig dog cat "                 # 왼쪽 공백 제거

> str_trim(' pig dog cat ', side = 'right')

[1] " pig dog cat"                # 오른쪽 공백 제거

 

 

 

 Q. 

# student.csv 파일을 읽고

> student <- read.csv('student.csv')

> student

   STUDNO   NAME         ID GRADE        JUMIN            BIRTHDAY          TEL HEIGHT WEIGHT DEPTNO1 DEPTNO2 PROFNO

1    9411 이진욱     75true     4 7.510232e+12 1975/10/23 00:00:00 055)381-2158    180     72     101     201   1001

2    9412 서재수     pooh94     4 7.502241e+12 1975/02/24 00:00:00 051)426-1700    172     64     102      NA   2001

...

19   9714 김주현      kimjh     1 7.803242e+12 1978/03/24 00:00:00 055)423-9870    179     81     102      NA     NA

20   9715   허우  wooya2702     1 7.802232e+12 1978/02/23 00:00:00 02)6122-2345    163     51     103      NA     NA

> library(stringr)


# 1. TEL 컬럼을 사용하여 지역번호 추출

# str_sub, str_locate 함수 사용

> student$TEL

 [1] 055)381-2158 051)426-1700 053)266-8947 02)6255-9875 031)740-6388 055)333-6328 051)418-9627 051)724-9618 055)296-3784

[10] 02)312-9838  02)6788-4861 055)488-2998 053)736-4981 02)6175-3945 051)785-6984 055)278-3649 02)381-5440  031)345-5677

[19] 055)423-9870 02)6122-2345

> str_sub(student$TEL, 

+         start = 1, 

+         end = str_locate(student$TEL, '\\)')[,1]-1)

 [1] "055" "051" "053" "02"  "031" "055" "051" "051" "055" "02"  "02"  "055" "053" "02"  "051" "055" "02"  "031"

[19] "055" "02"

# str_split 함수 사용 

> str_split(student$TEL, '\\)')  # 리스트 형식으로 출력, 각 층의 첫 번째 값을 가져오려면 반복문이 필요!

[[1]]

[1] "055"      "381-2158"


[[2]]

[1] "051"      "426-1700"


...


[[19]]

[1] "055"      "423-9870"


[[20]]

[1] "02"        "6122-2345"


> v1 <- c()   # 빈 벡터 생성 (for문은 바로 값을 저장할 수 없으므로)

> for(i in 1:length(student$TEL)){

+   v1 <- c(v1, str_split(student$TEL, '\\)')[[i]][1])

+ }

> v1

 [1] "055" "051" "053" "02"  "031" "055" "051" "051" "055" "02"  "02"  "055" "053" "02"  "051" "055" "02"  "031"

[19] "055" "02"



# 2. 여학생 정보만 추출 

> as.character(student$JUMIN)

 [1] "7510231901810" "7502241128467" "7506152123648" "7512251063421" "7503031639826" "7601232186327" "7604122298371"

 [8] "7609112118379" "7601202378641" "7610122196482" "7711291186223" "7704021358674" "7709131276431" "7702261196365"

[15] "7712141254963" "7808192157498" "7801051776346" "7808091786954" "7803241981987" "7802232116780"

> student[str_sub(student$JUMIN,7,7) == "2", ]

   STUDNO   NAME         ID GRADE        JUMIN            BIRTHDAY          TEL HEIGHT WEIGHT DEPTNO1 DEPTNO2 PROFNO

3    9413 이미경   angel000     4 7.506152e+12 1975/06/15 00:00:00 053)266-8947    168     52     103     203   3002

6    9511 김신영      bingo     3 7.601232e+12 1976/01/23 00:00:00 055)333-6328    164     48     101      NA   1002

...

16   9711 이윤나 prettygirl     1 7.808192e+12 1978/08/19 00:00:00 055)278-3649    162     48     101      NA     NA

20   9715   허우  wooya2702     1 7.802232e+12 1978/02/23 00:00:00 02)6122-2345    163     51     103      NA     NA



# 위의 변환식을 확용하여 성별 컬럼 추가("남자", "여자")

# ifelse문 사용

> student$GENDER <- ifelse(str_sub(student$JUMIN,7,7) == "2", "여자", "남자")

> student

   STUDNO   NAME         ID GRADE        JUMIN            BIRTHDAY          TEL HEIGHT WEIGHT DEPTNO1 DEPTNO2 PROFNO GENDER

1    9411 이진욱     75true     4 7.510232e+12 1975/10/23 00:00:00 055)381-2158    180     72     101     201   1001   남자

2    9412 서재수     pooh94     4 7.502241e+12 1975/02/24 00:00:00 051)426-1700    172     64     102      NA   2001   남자

...

19   9714 김주현      kimjh     1 7.803242e+12 1978/03/24 00:00:00 055)423-9870    179     81     102      NA     NA   남자

20   9715   허우  wooya2702     1 7.802232e+12 1978/02/23 00:00:00 02)6122-2345    163     51     103      NA     NA   여자

# if문 사용 (if문은 벡터연산이 불가하므로 for문 사용)

> v2 <- c()

> for(i in str_sub(student$JUMIN,7,7)){

+   if(i == "2") {

+     v2 <- c(v2,"여자")

+   } else {

+     v2 <- c(v2,"남자")

+   }

+ }

> v2

 [1] "남자" "남자" "여자" "남자" "남자" "여자" "여자" "여자" "여자" "여자" "남자" "남자" "남자" "남자" "남자" "여자" "남자" "남자" "남자" "여자"

> student$GENDER2 <- v2

> student

   STUDNO   NAME         ID GRADE        JUMIN            BIRTHDAY          TEL HEIGHT WEIGHT DEPTNO1 DEPTNO2 PROFNO GENDER GENDER2

1    9411 이진욱     75true     4 7.510232e+12 1975/10/23 00:00:00 055)381-2158    180     72     101     201   1001   남자    남자

2    9412 서재수     pooh94     4 7.502241e+12 1975/02/24 00:00:00 051)426-1700    172     64     102      NA   2001   남자    남자

...

19   9714 김주현      kimjh     1 7.803242e+12 1978/03/24 00:00:00 055)423-9870    179     81     102      NA     NA   남자    남자

20   9715   허우  wooya2702     1 7.802232e+12 1978/02/23 00:00:00 02)6122-2345    163     51     103      NA     NA   여자    여자





참고: KIC 캠퍼스 머신러닝기반의 빅데이터분석 양성과정

반응형
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday