R/강의복습

[22.08.18] 8일차(wordclou2/정규식/문자열/gsub/grep/substring)

peach_h 2022. 8. 21. 18:21
☆ 오늘 강의 요약 ☆

문자열 관련 함수 
sub(바꿀패턴,바뀔패턴,변수) : 처음 발견한 곳만 바꿔주는 함수
gsub(바꿀패턴,바뀔패턴,변수) : 전체에서 원하는 곳을 다 바꿔주는 함수
substr(변수, 시작, 끝) : 문자열에서 시작 위치와 끝 위치를 정하여 문자를 추출함
substring(데이터, 시작, 끝) : substr과 달리 시작 값만 입력해도 된다.
paste( ) : 문자열을 붙여 출력하는 함수
paste0( ) : 문자열을 공백없이 붙여 출력하는 함수
str_c (데이터, collapse="원하는문자") : 데이터를 원하는 문자로 나눌 수 있다.
strsplit(데이터, split="기준") : 데이터를 기준에 따라 나눠주는 함수 
grep("원하는 문자열", 데이터) : 데이터에서 원하는 문자열이 포함된 인덱스의 위치를 알려주는 함수
grep("원하는 문자열", 데이터, value = T) : 원하는 문자열이 포함된 값을 알려줌

메타문자 
? : 앞의 패턴이 0/1회 반복되는 경우 (0/1) 무조건 0 또는 1번 반복임.
     as? => a, as는 뜨지만 ass는 안뜬다.
* : 앞의 패턴이 0번 이상 반복되는 경우 (0 이상)
+ : 앞의 패턴이 1번 이상 반복되는 경우 / 무조건 있어야함 !!
.* : a와 b사이에 모든 문자가 0번 이상 존재한다
^[^x]+$ : x를 제외한

 

 

 

 

wordcloud2 활용하기 ( figPath 오류 극복하기 )

 

어제 wordcloud2를 사용하여 다양한 모양으로 wordcloud를 만들 수 있었다.

그러나 다른 이미지의 모양대로 wordcloud만들기는 실패했다..

실패의 이유는 wordcloud2를 구버전으로 설치했기 때문!

이렇게 오류가 발생하면 Github에서 직접 설치해야한다.

그래서 새 버전으로 다시 설치하고 나니 성공했다 !

 

# wordcloud2 새버전으로 설치하기
library("KoNLP")
library("devtools") # Github에서 다운받아 설치해주는 라이브러리

devtools::install_github("lchiffon/wordcloud2")

library(hash)
library(tau)
library(Sejong)
library(KoNLP)
library(dplyr)
library(stringr)
library(tm)
library(SnowballC)
library(RColorBrewer)
library(tidyverse)
library(wordcloud2)
library(nord)


useNIADic()
useSejongDic()

 

wordcloud 만들 트위터 파일 가져오기
# 트위터 파일 가져오기
setwd("c:/r_work/data")
twitter <- read.csv("twitter.csv",
                    header = T,
                    stringsAsFactors = F,
                    fileEncoding = "UTF-8")

class(twitter)
head(twitter)
str(twitter)


# 변수명 수정
twitter <- rename(twitter,
                  no = 번호,
                  id = 계정이름,
                  date = 작성일,
                  tw = 내용)

# 특수문자 제거 
twitter$tw <- str_replace_all(twitter$tw, "\\W", " ")
head(twitter$tw)

# 트윗에서 명사추출 - list타입으로 보낸다.  
nouns <- extractNoun(twitter$tw)
nouns[1:20]

#table( nouns ) #에러발생 
ul <- unlist(nouns)
ul[1:40]

#unlist - list -> vector로 바꾸기 
# 추출한 명사 list를 문자열 벡터로 변환, 단어별 빈도표 생성
wordcount <- table(unlist(nouns))
wordcount[1:10 ]
# 데이터 프레임으로 변환
df_word <- as.data.frame(wordcount, stringsAsFactors = F)

# 변수명 수정
df_word <- rename(df_word,
                  word = Var1,
                  freq = Freq)


# 두 글자 이상 단어만 추출
df_word <- filter(df_word, nchar(word) >= 2)

# 가장 빈도수가 높은 300개만 추출
dim(df_word)
df <- df_word %>% arrange( desc(freq)) %>% head(300) 
dim(df)

기존의 파일 그대로로 사용하기엔, 단어가 너무너무너무 많았다.

그래서 2글자 이상이고, 빈도수가 높은 순으로 300개만 추출했다.

 

 

# lettercloud와 wordcloud2의 figpath는 웹으로만 가능하다
# 오른쪽 화면 Viewr의 아이콘을 클릭해서 브라우저로 확인가능.
# 데이터 항목이 많을 경우 오래걸린다.
# 애플로고모양
wordcloud2(df, color = "skyblue",size=1,
           figPath="C:/r_work/data/images/apple.png",
           backgroundColor = "black" )

# 토끼모양
wordcloud2(df, color = "random-light",size=1,
           figPath="C:/r_work/data/images/rabbit2.png" )

figpath와 letterCloud를 실행한 후에는 체크해둔 아이콘을 눌러 브라우저로 열어야 결과가 보인다. ( 뜰때까지 새로고침도 해줘야함)

드디어 wordcloud2 성공 !! 트위터 자료라 그런가 내용이 쫌 그렇지만 아주 맘에든다 ~~~~~~~~

 

 

 

 

LetterCloud 사용하기
# 지정한 문자열 모양대로 cloud를 생성함
letterCloud(df,"R")

R 모양대로 잘 생성된 모습

 

 

 

# 문자열처리
정규식 ?

패턴을 표현하기 위해 규칙을 정의하는 방법

메타문자와 정규문자를 사용

문자나 패턴을 정의하는 것 !

 

# sub = 대체하다 / g = global
birth <- "2012-09-09"
#  2012년 09월 09일 로 뜨게하기
birth <- paste0(substr(birth,1,4),"년",
               substr(birth,6,7),"월",
               substr(birth,9,10),"일")
birth

paste( ) 가 아닌 paste0( ) 을 사용하면 공백없이 출력할 수 있다.

substr(변수, 시작, 끝) : 문자열에서 시작 위치와 끝 위치를 정하여 문자를 추출하는 함수

 

 

 

class / unclass
class(birth) # 변수의 데이터 타입 확인
unclass(birth) # 클래스해체, 내부구조를 보기위해 사용

 

 

문자열 잘라내기 (substr 함수)
# 문자열을 잘라내는 함수
w <- "Data Analytics"

# R은 인덱스가 꼭 1부터 시작함. 마지막 값도 포함함
substr(w, start=1, stop=4) 
substr(w, start=1, stop=1)
substr(w, 3, 6) # 3번부터 6번까지

substr(w, 6, 14) # 주의할점 : 시작값 종료값 반드시줘야함.

** substr(a,1,4) : a에서 1부터 4까지 출력

 

 

 

 

R의 특징
# 기본적으로 R은 인자가 스칼라/벡터(이게기본임)
substr(c("red","blue","cyan","magenta"),1,3)

# 첫번째 인자가 벡터이면 동일하게 적용함
substr(c("red","blue","cyan","magenta"),
       c(1,2,3,4),c(1,2,3,4))

# 아래 두코드는 같은 뜻을 가진다
substr(c("red","blue","cyan","magenta"),
       c(1,2,3,4),c(3,4))

# 개수가 안맞을 경우, R이 알아서 값을 반복해 맞춰줌
substr(c("red","blue","cyan","magenta"),
       c(1,2,3,4),c(3,4,3,4))

같은 값이 나옴을 확인할 수 있음.

 

 

substring 함수 활용하기
# substr과 substring의 차이
substring("abcdef", 1:6, 1:6)
substr("abcdef", 1:6, 1:6)

substring은 substr을 6번 쪼개서 한 것과 같다.

 

# substring은 첫번째 인자만 사용해도 된다
substring(w, first=6)
substring(w,6,10)
substring(w, first=c(1,6), last=c(4,14)) # 1,4  6,14

 

 

# 벡터만들기
classname <-c('Data Analusics', 'Data Mining',
              'Data Visulaization')
substr(classname, 1,4)
substr(classname, 6,100) # 뒷자리에 아무거나 큰수 넣으면 잘라줌
substring(classname, 6)

 

 

# 둘이 같은 표현식임
substr(classname, 6, nchar(classname))
substr(classname, 6, c(14,11,18))

substr 함수에 벡터도 사용 가능하다 !

 

 

문제1) 끝에 2글자만 추출하기
# 문제1. 각자 끝에 2글자만 추출하기
countries <- c("Korea, KR", "United States, US",
               "China, CN", "Canada, CA")
nchar(countries)
substr(countries, nchar(countries)-1,nchar(countries))

nchar를 활용해서 뒤에서 부터 문자를 추출할 수 있다.

 

 

# islands 자료 활용하기
# 새자료를 가져오면 항상 미리 봐볼 것
class(islands)
names(islands)
islands[1:10]

# 나라이름만 모으기
land <- names(islands)
land

islands는 나라와 인구수를 나타내는 데이터인듯하다.

 

 

island 같은 데이터 만드는 법
# 이런식으로 이름을 주면 islands 같은 파일을 만들 수 있다.
x <- c(1,2,3,4,5)
names(x) <- c("one", "two", "three", "four", "five")
x
x["one"]
x["two"]
x["three"]

# 열의 이름을 갖고 와서 새로운 벡터를 만들었음
land <- names(islands)
land

열 이름인 나라 이름으로 land라는 새로운 벡터 만들기

 

 

 

New가 들어간 나라 찾기
# grep = 찾는 문자열이 포함된 인덱스의 위치를 알려줌.
grep("New", land)
land[grep("New", land)]

** grep("원하는 문자열", 데이터) : 데이터에서 원하는 문자열이 포함된 인덱스의 위치를 알려주는 함수

 

 

문제 1) 시작 글자가 S인 나라 찾기
grep("^S", land, ignore.case= T)
land[grep("^S", land, ignore.case= T)]

 

 

문제 2) n으로 끝나는 나라 찾기
grep("n$", land, ignore.case= T)
land[grep("n$", land, ignore.case= T)]

 

 

문제 3) ha가 들어가는 나라 찾기
grep("ha",land, ignore.case= T)
land[grep("ha",land, ignore.case= T)]

 

 

 

문제4) A로 시작하고 a로 끝나는 나라 찾기
grep("^A.*a",land, ignore.case= T)
land[grep("^A.*a",land, ignore.case= T)]

# 2번 거쳐서도 할 수 있음.
a <- land[grep("^A", land, ignore.case=T)]
land[grep("a$", a, ignore.case=T)]

 

 

 

 

gsub 함수 활용하기
Data -> Business로 바꾸기
#Data -> Business로 바꾸기
txt <- "Data Analytics is useful, Data Analytics is also interesting"

sub("Data","Business",txt) # 첫번째 데이터 하나만 바뀐다
gsub("Data","Business",txt) # 전체를 다 바꾼다.

sub, gsub 함수를 이용함

 

 

확장자가 csv인 파일 찾아서 xlsx로 바꾸기
#확장자가 csv인 파일만 찾아서 xlsx로 바꾸기
x <- c("test1.csv", "test2.csv", "test3.xlsx", "aaa.csv", "bbb.xlsx")
gsub("csv","xlsx",x)

이정도는 이제쉽다 ㅋ

 

 

gsub함수 정규식 메타문자
x <- "123AlittleconanBC98ABC AB ABC C"
# A 또는 B 또는 C가 @로 바뀐다
gsub("[ABC]", "@", x) 
gsub("A|B|C", "@", x)
gsub("[[A-C]", "@", x)

셋다 같은 말임을 알 수 있었다.

 

 

gsub("ABC", "@", x) # ABC를 찾아서 @로 바꾼다
gsub("(AB)|C", "@", x) # AB 또는 C를 찾아서 @로 바꾼다
gsub("A|(BC)", "@", x) # BC 또는 A를 찾아서 @로 바꾼다

"[ABC]"는 A, B, C를 모두 바꾼다.

"ABC"는 "ABC"를 찾아서 바꾼다.

gsub함수는 |(or) 연산이 가능하다 !

 

 

 

grep 함수 활용하기
words <- c("ct", "at", "bat", "chick", "chae", "cat", "chse",
           "cheanomeles", "chase", "chasse", "mychasse", "chasssse",
           "chassssse", "chasssssse",
           "cheap", "check", "cheese", "hat", "mycat", "mycheese",
           "asdfcccasdf", "asdfasdf")

grep("che",words) # 인덱스로 나옴
grep("che",words, value=T) # 값을 준다

grep만 사용하면 인덱스 번호로 결과가 나와서 다시한번 인덱싱해야하는 번거로움이 있었는데, value = T를 추가하면 값을 바로 볼 수 있다.

 

grep("^che",words, value=T) # che로 시작하는
grep("t$",words, value=T) # t로 끝나는
grep("[ch]", words, value=T) # c나 h를 포함하는
grep("^[ch]", words, value=T) # c나 h로 시작하는
grep("[at]", words, value=T)  # a나 t를 포함하는
grep("ch|at", words, value=T) # ch나 at를 포함하는
grep("^ch|^at", words, value=T) # ch나 at로 시작하는
grep("ch(e|i)ck", words, value=T) # check / chick를 포함하는

 

메타문자 한눈에 보기

 

메타문자
^x x로 시작하는
x$ x로 끝나는
[x] x를 포함하는
[xy] x나 y를 포함하는
x | y x나 y를 포함하는
^[xy] x나 y로 시작하는
^x | ^y x나 y로 시작하는
x(a|b)y xay, xby를 포함하는

 

 

 

# grep 명령어 ? * +
특정 패턴의 반복여부를 따진다
메타문자
? ? 앞의 패턴이 0 / 1 회이상 반복되는 경우
* * 앞의 패턴이 0번이상 여러번 반복되는 경우
+ + 앞의 패턴이 1회 이상 반복되는 경우

 

 

? : 0 또는 1번
# grep 명령어 ? * + 특정 패턴의 반복여부를 따진다.
grep("chase" ,words, value=T)

# ? 앞의 패턴이 0번 이상 반복
# s라는 문자가 0번 또는 1번 나오는 경우
grep("chas?e" ,words, value=T)

 

 

* : 0번 이상 여러번
# * 0번 이상 여러번
grep("chas*e" ,words, value=T) # s가 없는 경우, 1,2,3,.. 다나옴

# ss가 한번도 없거나 1(ss) 2(ssss) 3(ssssss)
grep("cha(ss)*e" ,words, value=T)

 

 

+ : 앞의 패턴이 1회 이상 반복
# s가 적어도 한번이상
grep("chas+e" ,words, value=T)

 

? = 무조건 0 또는 1번 반복임. as? => a, as는 뜨지만 ass는 안뜬다.

* = 0회 이상 반복. = 있다. 존재한다.

+ = 무조건 있어야함 !!

 

 

메타문자 활용하기
a든 e든 앞이 ch, se면 추출하기
# a든 e든 앞이 ch, 뒤가 se면 다나옴 ( 개수도 상관 X )
grep("ch(a*|e*)se" ,words, value=T)

이게젤어려운거같다

 

 

C로 시작하는 것, t로 끝나는 것 / C로 시작하고 t로 끝나는것
# c로 시작하는 것, t로 끝나는 것
grep("^c", words, value=T)
grep("t$", words, value=T

^를 쓰면 시작하는것, $를 쓰면 끝나는것.

다 문자 뒤에 기호를 쓰는데, ^만 문자앞에 붙인다

 

 

# c로 시작하고 t로 끝나는 것
grep("^c.t$", words, value=T) # ct가 안나옴.

# . : 모든 문자 / * : 0번 이상이다.
# .* 모든 문자가 0번 이상 있다
grep("^c.*t$", words, value=T)

.* : 모든 문자가 0번 이상 있다 !

a.*b : a와 b사이에 모든 문자가 0번 이상 존재한다

 

 

 

A로 시작하고 a로 끝나는
grep("^A.*a$", land, value=T) # 앞의 land 벡터에 A로 시작하고 a로 끝나는 나라 선택하기

 

 

 

c가 들어간 문자열 제외하기
grep("^[^c]+$", words, value=T)

^[^x]+$ : x를 제외한

 

 

islands 자료에 메타문자 활용하기
문제 5) T로 시작하고 두번째 글자가 a 또는 i가 들어가는 나라
grep("^T(a|i)", land, value=T)

 

문제 6) I나 J로 시작하는 나라
grep("^[IJ]", land, value=T)

[ ab] = a거나 b / ^ = 첫글자

 

문제 7) o가 안들어가는 나라
grep("^[^o]+$", land, value=T)

 

문제 8)  H나 K로 시작하고 끝이 u인 나라
grep("^[HK].*u$", land, value=T)

 

 

 

벡터 전체를 합치기
# 벡터 전체를 합산하기
paste(land, collapse=" ")

# 벡터로 전달된 모든 문자 합치기
library("stringr")
l <-str_c(land,collapse=" " )
l

paste 함수와 str_c함수로 벡터속 문자를 합칠 수 있다

 

 

다시 분해하기
# 다시분해하기 - 토큰 분해하기
dl <- strsplit(l, split=" ")
class(dl)
d1

** strsplit(데이터, split="기준") : 데이터를 기준에 따라 나눠주는 함수

strsplit을 이용해 공백으로 데이터들을 다시 쪼갰다. 문자열에서 다시 list가 된 모습

list는 연산하기 어렵기 때문에 unlist 한 후 사용하도록 하자 !

 

 

 

# 신라 호텔 리뷰 파일 활용하기
# 파일 가져오기
setwd("c:/r_work/data")
test <- readLines("서울_신라호텔리뷰.txt", encoding="UTF-8")
test[1:10]
head(test)

 

 

리뷰 점수에서 숫자만 추출하기
# 리뷰 점수에서 숫자만 추출하기
result1 <- grep( "리뷰 점수", test, value=T)

result2 <- gsub("리뷰 점수: ", "", result1)
result2
class(result2)

grep 함수로 "리뷰 점수"가 포함 된 데이터를 추출한 후, gsub 함수로 "리뷰 점수: "를 제거해서 숫자만 남게함.

데이터 타입이 문자열이다.

 

 

 

리뷰 점수로 표만들기
# 빈도수 계산을 위해 factor로
result3 <- as.factor(result2)
result3

table(result3)
str(result3)
head(result3)


# 데이터프레임으로 만든후 표만들기
a <- data.frame(result3)
qplot(dat=a, x=result3)

character 타입으로는 빈도수를 계산할 수 없다.

1. 우선 result3의 데이터 타입을 factor로 바꿔준다.

2. 그리고 result3을 데이터 프레임으로 만들어 준다.

3. 그후 qplot으로 빈도수 그래프를 생성하면 끝 !!

되게 좋은 호텔인가보다.

 

 

 

# 영화배우 파일 활용하기
# 파일 가져오기
setwd("c:/r_work/data")
mo = read.csv("영화배우와_출연작품.csv", fileEncoding = "euc-kr")

head(mo)

fileEncoding을 안썼더니 계속 오류가남 ㅠ 꼭 써줘야하나보다

미리 구조 살펴보기는 필수다

 

 

배우별로 총 관객수 구해서 그래프 만들기
# 배우 별 관객수 총합 구하기
mo1 <-mo %>% group_by(배우명) %>% 
  summarize(sum_p=sum(관객수)) %>% 
  head(10)

mo1

 

 

그래프 만들기
ggplot(mo1, aes(x=배우명,y=sum_p)) +  geom_col()

 

 

심심해서 만들어본 boxplot
qplot(data=mo, x=배우명, y=관객수)
qplot(data=mo, x=배우명, y=관객수, geom="boxplot")

qplot이 제대로 만들어지나 보고
boxplot을 만들어보았다.

boxplot의 모습을 보고 대략적인 데이터 파악이 가능하다.

 

 

 

~ 오늘의 공부 후기 ~

하루동안 워드클라우드, 정규식, 자료활용, 날짜시간까지...
정말 쉽지않은 하루였다
특히.. 메타문자는 너무 헷갈린다ㅠ 복습이 매우필요할것으로예상..

※ 사용한 교재 : 쉽게 배우는 R 데이터 분석 / 저자 : 김영우