본문 바로가기
R 과 데이터분석/기초 문법 ~ 머신러닝

[R 데이터분석] 2장. 데이터 자료구조 & 문자열 처리와 정규표현식

by JoyfulS 2019. 9. 12.

# chap02_DataStructure

# 데이터의 유형과 자료구조 및 관련함수 & 문자열 처리

# 1. Vector

# 2. Matrix

# 3. Array  

# 4. DataFrame

# 5. LIST 

# 6. subset
# 7. 문자열 처리와 정규표현식  


# 1. Vector
# - 동일한 자료형을 갖는 1차원 배열구조
# - 생성함수 : c(), seq(), rep()

# c()함수 
x <- c(1,3,5)
y <- c(3,5)
x[3]
y

# 집합관련 함수 
union(x, y) # 합집합(x+y) 
setdiff(x, y) # 차집합(x-y) 
intersect(x, y) # 교집합(x^y) 

z <- c(1:5,"6")
z # "1" "2" "3" "4" "5" "6"

names <- c("홍길동", "이순신", "유관순")
names
length(names) # 3

y <- c(1:10, -2:5)
y

# seq()
help(seq)
seq(1, 9, by = 2) # 1 3 5 7 9
seq(9, 1, by = -2) # 9 7 5 3 1

# rep()
help(rep)
rep(1:4, 2) # 1 2 3 4 1 2 3 4
rep(1:5, each=2) # 1 1 2 2 3 3 4 4 5 5

# 색인(index) : 1부터 ~ n
a <- seq(1, 100, by = 3)
a
length(a) # 34
a[5] # 5번째 원소 : 13
a[length(a)-4] # 34-4 = 30 : 88

# 조건식 이용 
a[a<=30]
a[a>=10 & a<=30] # &(and)
a[a>=10 | a>=30] # |(or)

# a의 홀수번째 값 추출 
a2 <- a[seq(1,length(a), 2)]
a2

# 2. Matrix 
# - 동일한 자료형을 갖는 2차원 배열구조
# - 생성함수 : matrix(), rbind(), cbind()

# (1) matrix()
m1 <- matrix(data=c(1:5))
m1
# 차수 
dim(m1) # 5(행) 1(열)

m2 <- matrix(data = c(1:9), nrow =3 , ncol =3 , byrow=TRUE)
m2
dim(m2) # 3 3
mode(m2) # "numeric"
class(m2) #  "matrix"

# mode vs class
# mode : 자료형 반환 
# class : 자료구조 반환 


# (2) rbind()
v1 <- c(1:5)
v2 <- c(6:10)
v3 <- c(11:15)
v1; v2; v3

m3 <- rbind(v1, v2, v3)
m3
dim(m3) # 3 5
class(m3) # "matrix"

# (3) cbind()
m4 <- cbind(v1, v2, v3)
m4
dim(m4) # 5 3
class(m4) # "matrix"

# matrix index
# 형식) 변수[행index, 열index]
m4[1,] # 1행 전체 
m4[,3] # 3열 전체 
m4[(2:4),(1:3)] # 블럭 참조 
m4[c(2:3,5), c(1,3)]

x1 <- c(1:5)
x2 <- c(10,20,30,40,50)

xy <- rbind(x1, x2)
# ADSP 기출문제 
# 1. xy[1,]는 x1과 같다.(o)
# 2. xy[,1]는 x2와 같다.(x)
# 3. 2x5 행렬 구조이다.(o)
# 4. matrix 자료구조이다.(o)
xy[1,]
xy[,1]
dim(xy) # 2 5

xy
# matrix에 칼럼 지정 
colnames(xy) <- c("col1", "col2", "col3", "col4", "col5")
xy

var <- 1:12 # c(1:12) - 1차원 배열 
mat <- matrix(var, nrow = 3) # 1차원 -> 2차원 
mat

# matrix 처리 함수 
#apply(X=mat, MARGIN = 1/2, FUN = )

# 행단위 합계/평균/표준편차   
apply(mat, 1, sum)
apply(mat, 1, mean)
apply(mat, 1, sd)

# 열단위 합계/평균/표준편차
apply(mat, 2, sum)
apply(mat, 2, mean)
apply(mat, 2, sd)

# 사용자 정의 함수 
f <- function(x){
   calc = x * c(1,2,3,4)
   return(calc)
}

apply(mat, 1, f)
#     [,1] [,2] [,3]
#[1,]    1    2    3
#[2,]    8   10   12
#[3,]   21   24   27
#[4,]   40   44   48


# 3. Array 
# - 동일한 자료형을 갖는 3차원 배열구조 
# - 생성 함수 : array()

v <- 1:12 # 1차원 배열 
arr <- array(data=v, dim = c(3,2,2)) # c(행,열,면)
arr

# index 형식) 변수[행index,열index,면index]
arr[,,1] # 1면 전체 
arr[,,2] # 2면 전체 

arr[c(1:2),,1]# 1면 1~2행 

arr[c(1,3),2,2]# 2면 1,3행, 2열 : 10 12

data()
data("iris3")

dim(iris3) # 50(행)  4(열)  3(면)
mode(iris3) # "numeric" : 자료형 
class(iris3) # "array" : 자료구조 

iris3[,,1] # 1면 - 200개 
iris3[,,2] # 2면 - 200개 
iris3[,,3] # 3면 - 200개 


# 4. DataFrame 
# - 행렬구조의 2차원(matrix)
# - 열 단위 서로 다른 자료형
# - 생성함수 : data.frame()

# 1) vector 이용 
eno <- 1:3
ename <- c("홍길동", "이순신", "유관순")
age <- c(35, 45, 25)
pay <- c(250, 350, 200)

emp <- data.frame(ENO=eno, NAME=ename, AGE=age, PAY=pay)
emp
dim(emp) # 3 4
class(emp) # "data.frame"

# DF$column
pay <- emp$PAY
sum(pay); mean(pay)
# 800
# 266.6667
sd(pay) 
# 76.37626

age <- emp$AGE
age
mean(age) # 35

 

 

### 사용된 파일은 https://joyfuls.tistory.com/4 에서 다운 받으실 수 있습니다.

 

# 2) file read 이용 
getwd()
setwd("c:/2_Rwork/Part-I")
emp_txt <- read.csv("emp.txt", sep="") # 칼럼 구분자 : 공백 
class(emp_txt) # "data.frame"
emp_txt

emp_csv <- read.csv("emp.csv", sep=",")# 칼럼 구분자 : 콤마 
emp_csv
class(emp_csv) # "data.frame"

pay <- emp_csv$pay
mean(pay) # 370

# example
sid = 1:3
score = c(90, 85, 88)
gender = c('M', 'F', 'M')
name = c("홍길동", "유관순", "이순신")

# 문1) 4개 vector를 이용하여 student 데이터프레임 생성 
student <- data.frame(sid, score, gender, name)
student

# 문2) 평균 점수 출력 
score <- student$score
mean(score) # 87.66667

# 문3) 점수에 대한 표준편차 출력 
sd(score) # 2.516611

# 문4) '유관순' 학생 정보 출력 
student[2, ]


# 5. LIST
# - 서로 다른 자료형(숫자형, 문자형, 논리형)
# - 서로 다른 자료구조(1차원, 2차원, 3차원)
# - 데이터 참조 : key 이용(cf : index 이용) 
# - 생성 함수 : list(key=value)

# 1) key 생략 
lst <- list("홍길동", 35, "이순신", 45)
lst
#[[1]] <- 기본 key : [[n]]
#[1] "홍길동" <- value

#[[2]] <- 기본 key
#[1] 35 <- value

#[[3]] <- 기본 key
#[1] "이순신" <- value

#[[4]] <- 기본 key
#[1] 45 <- value

# key 이용 -> data 참조
lst[[3]] # "이순신"
lst[[2]] # 35


# 2) key 이용(key=value)
lst2 <- list(first=c(1:5), second=c(6:10))
lst2
#$first <- key
#[1] 1 2 3 4 5 <- value

#$second <- key
#[1]  6  7  8  9 10 <- value

# key 이용 -> data 참조 
lst2$first # 1 2 3 4 5
lst2$second # 6  7  8  9 10

# $ 기호 
# data.frame : DF$column
# list : LIST$key

# example
member <- list(name=c("홍길동", "유관순"),
               age=c(35, 25),
               gender=c('남자', '여자'),
               addr=c('한양시', '충남시'))
member

member$name # "홍길동" "유관순"
member$name[2] # "유관순"
member$age[1] <- 38 # 값 수정 
member$age # 38 25
member$id <- c("hong", "yoo") # key 추가  
member
member$id <- NULL # key 제거 

# 유관순 주소지 -> "안산시" 변경 
member$addr[2] <- "안산시"
member

# 3) 서로 다른 자료구조(1:vector, 2:matirx, 3: array) 
lst3 <- list(one=c("one", "two", "three"),
             two=matrix(1:9, nrow = 3),
             three=array(1:12, c(2,3,2)))
lst3
# $one : 1차원 
# $two : 2차원 
# $three : 3차원 


# 4) list 형변환
x <- list(1:5) # key 생략 
x
#[[1]] <- key
#[1] 1 2 3 4 5 <- value
x[[1]][4] # 4

# list -> vector 형변환 
vec <- unlist(x)
vec # [1] 1 2 3 4 5
vec[4] # 4

# list -> matrix 형변환 
mul_list <- list(row1 = list(1,2,3),
                 row2 = list(10,20,30),
                 row3 = list(100,200,300))
mul_list

#$row1 <- key 
#$row1[[1]] <- 기본 key 
#[1] 1

#$row1[[2]]
#[1] 2

#$row1[[3]]
#[1] 3

#do.call(func, data)
row_mat <- do.call(rbind, mul_list)
row_mat
#   [,1] [,2] [,3]
#row1 1    2    3   
#row2 10   20   30  
#row3 100  200  300
class(row_mat) # "matrix"

col_mat <- do.call(cbind, mul_list)
col_mat
class(col_mat) # "matrix"


# 5) list 처리 함수 

# apply 유형 관련 함수 
# apply() : matrix, data.frame
# lapply() : list, key=value 반환 
# sapply() : list, value 반환 

a <- list(1:5)
b <- list(6:10)
a
b

lapply(X=c(a,b), FUN = max)
#[[1]] <- a
#[1] 5

#[[2]] <- b
#[1] 10

sapply(X=c(a,b), FUN = max)
# [1]  5 10

sapply(X=c(a,b), FUN = sum)
# 15 40

 


# 6. subset
# - 특정 DF 대상 -> 또 다른 DF
help(subset)
# subset(x, subset, select, drop = FALSE, ...)

x <- 1:5
y <- 6:10
z <- letters[1:5] # a~z
df <- data.frame(x, y, z)
df
class(df)

# 1) 조건식 이용 
df1 <- subset(df, x >= 3)
df1
class(df1) # "data.frame"

df2 <- subset(df, y <=8)
df2

df3 <- subset(df, x>=2 & y <=8) # &(and)
df3

# 2) 칼럼 선택 이용 
df4 <- subset(df, select = c(x, y))
df4

# 3) 조건식 & 칼럼 선택 
df5 <- subset(df, y <=8, select = c(x, y))
df5

# example
iris # 기본 dataset - 붓꽃
dim(iris) # 150   5
names(iris)
#[1] "Sepal.Length" "Sepal.Width" 
#[3] "Petal.Length" "Petal.Width" 
#[5] "Species" 

# 3번 칼럼 평균 
mean(iris$Petal.Length) # 3.758

# 문) iris dataset 대상으로 subset 생성하시오.
# <조건1> 1,3,5번 칼럼 대상 
# <조건2> 3번 칼럼은 평균 이상 선택 
iris_df <- subset(iris, 
                  Petal.Length >= mean(iris$Petal.Length), 
                  select=c(Sepal.Length, Petal.Length, Species))
iris_df
dim(iris_df) # 93  3

 


# 7. 문자열 처리와 정규표현식 
install.packages("stringr") # 설치 
# URL 'https://cran.rstudio.com/bin/windows/contrib/3.6/stringr_1.4.0.zip'
library(stringr) # memory loading

str_extract("abc123bad123", "[0-9]{3}") # "123"
str_extract_all("abc123bad123", "[0-9]{3}") # list
#[[1]] <- key
#[1] "123" "123" <- value
str_extract_all("abc123bad123", "[a-z]{3}") # list

# 1) 반복수 메타문자 : []:1회, {n} :n반복 
string <- "hong35lee45kang55유관순25이사도시35"
string

# 연속된 영소문자 3자 이상 추출 
str_extract_all(string, "[a-z]{3}") # 3
str_extract_all(string, "[a-z]{3,}") # 3이상 
str_extract_all(string, "[a-z]{3,4}") # 3~4

# 연속된 한글 3자 이상 추출 
str_extract_all(string, "[가-힣]{3,}") # [1] "유관순"   "이사도시"

# 나이 추출하기 
age <- str_extract_all(string, "[0-9]{2}")
age # list

# unlist : list -> vector
age <- unlist(age)
# string -> numeric
age <- as.numeric(age)
mean(age) # 39


# 2) 단어와 숫자 관련 메타문자 
# 단어(word) : \\w
# 숫자(digit) : \\d
# 엔터키, 탭키 : \n, \t

# 주민번호 양식 
jumin <- "123456-5234567"
jumin

str_extract_all(jumin, "[0-9]{6}-[1-4][0-9]{6}")
str_extract_all(jumin, "\\d{6}-[1-4]\\d{6}")

# 이메일 양식 
email <- "kp1234@abcde.com" # id@host
email
# \\w : 영문자, 숫자, 한글, 특수문자 
str_extract_all(email, "[a-z]\\w{4,}@[a-z]{3,}.[a-z]{2,}")


# 3) 특정 문자열 제외 : ^ 메타문자 
string # "hong35lee45kang55유관순25이사도시35"
first <- str_extract_all(string, "[^0-9]{3,}") # 숫자 제외 
first
class(first) # "list"

# 한글 이름 추출 : 영문자 제외   
names <- str_extract_all(first[[1]], "[^a-z]{3,}")
names

names <- unlist(names) # vector
names # [1] "유관순"   "이사도시"


# 4) 문자열 길이 
length(string) # 1
str_length(string) # 28

# 5) 문자열 위치 
str_locate_all(string, 'g')

# 6) 문자열 교체 
str_replace_all(string,'g', 'k')

# 7) 부분 문자열 
sub_str <- str_sub(string, start = 3, end = 5)
sub_str

# 8) 문자열 분리(split)
string2 <- "홍길동,이순신,유관순"

names <- str_split(string2, ",")
names # list

names <- unlist(names)
names #  "홍길동" "이순신" "유관순"

# 9) 문자열 결합(join) : 기본 함수 
name <- paste(names, collapse = ' ')
name # "홍길동 이순신 유관순"

# 10) 특수문자($, ,) 제외 
num <- "$123,466"
num

# 특수문자 제거 
tmp <- str_replace_all(num, "\\$|\\,", "")
tmp
# 숫자형 변환 
data <- as.numeric(tmp)
data * 2




댓글