반전공자

R 통계분석 (2주차) 본문

데이터분석/R

R 통계분석 (2주차)

하연01 2021. 3. 10. 02:35

이번주차에는 데이터를 관리하고 정제하는 방법에 대해서 배웠다. 

 

I. R 데이터 불러오기, 저장ㅎ기 (dat, csv, txt, Rdata) 

 

# 데이터 저장 및 불러오기 

# 저장하기 
save(fruit, file="test.dat")

# 불러오기 
load("test.dat")

 

# 엑셀 데이터 저장 및 불러오기 

# 엑셀파일 저장
write.csv(fruit, "fruit.csv")

# 엑셀파일 불러오기 
scoer = read.csv("score.csv")

 

# 일반 데이터의 저장 및 불러오기 

# ** 저장하기 **
vec1 = c(1,2,3)
vec2 = c(4,5,6)
mat = rbind(vec1, vec2)

save(mat,file="testmat.txt") # 텍스트파일로 저장하기
dfile = load("testmat.txt")
dfile # 무엇을 읽어들였나?
[1] "mat" # mat 오브젝트를 읽어들였다.


# ** 불러오기 ** 
b = scan("birth.text", what="")
c = read.table("birth.txt", header=T)

 

# 엑셀 입출력 유의점 

 

1. str() 함수를 통해 구조를 파악하면 값의 유형을 알 수 있는데, 만약 factor 값이 아닌데 factor 값으로 지정되어있다면 올바른 형식으로 고쳐주어야 한다. 

x$name = as.character(x$name) # 혹은 
x = read.csv("a.csv", StringAsFactors = FALSE)

 

2. header가 없는 경우 - 컬럼 이름을 부여해주자

names(x) = c("id","name","score")

 

3. 숫자값 사이에 NIL이 저장되어있는 경우 - NA로 바꿔주기

x = read.csv("c.csv", na.Strings = c("nil")

 

 

# 객체의 파일 입출력

# x와 y 값을 생성
x = 1:5
y = 6:10

# xt.RData 파일에 x,y 값을 저장한다.
save(x,y,file="xy.RData")
# load()하여 불러와졌는지 결과를 확인하기 위한 과정 
rm(list=ls()) # 사용변수 모두 삭제 
# x와 y가 모두 삭제되었음을 알 수 있다.
x
Error : object 'x' not found 
y
Error : object 'x' not found 

# x, y를 로드해보자.
load("xy.RData")
x
[1] 1 2 3 4 5
y
[1] 6 7 8 9 10

 

 

 

 

II. R 데이터 조작, 처리, 가공 : 기본함수 

 

# apply 계열 함수

 

- 벡터, 행렬, 데이터 프레임에 임의의 함수를 (전체적으로) 적용한 결과를 얻기 위한 함수 

- 데이터 전체에 대해 함수를 한번에 적용하는 연산 수행을 통해 데이터 조작, 처리 (원하는 형태로 데이터 조작, 처리 가능)

apply() # 배열 또는 행렬에 주어진 함수를 적용한 뒤 그 결과를 벡터, 배열 또는 리스트로 반환
lapply() # 벡터, 리스트 또는 표현식에 함수를 적용하여 그 결과를 리스트로 반환 
sapply() # lapply()와 유사하지만, 결과를 벡터, 행렬 또는 배열로 반환 (심플한 자료구조)
tapply() # 벡터에 있는 데이터를 특정 기준에 따라 그룹으로 묶은 뒤 각 그룹마다 주어진 함수를 적용하고 그 결과를 반환
mapply() # sapply()의 확장된 버전으로, 여러개의 벡터 또는 리스트를 인자로 받아 함수에 각 데이터들을 모두 적용한 결과 등을 반환

 

 

 

< apply()

apply(x, margin, fun) 

# x : 배열 , margin : 함수를 적용하는 방향 (1: 행, 2: 열 c(1,2): 행,열 모두), fun : 적용할 함수
apply(x, margin, fun) 

# iris 데이터들에 대해 꽃받침 길이 및 넓이, 꽃잎 길이 및 넓이 각각의 합계 구하기 
# 행 상관없이 1,2,3,4열에 대해 열 단위로 합계 구하기 
apply(iris[,1:4], 2, sum)
Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
       876.5        458.6        563.7        179.9 

 

< lappy()

lapply(x, fun, 추가인자)

lapply(x, fun, 추가인자) # 결과를 리스트로 반환 / x : 배열, 리스트, 표현식 fun : 적용할 함수
x = list(a = 1:3, c = 4:6)
 x
 # 결과
$a
[1] 1 2 3

$c
[1] 4 5 6

lapply(x, mean)  # x(리스트)의 평균 구하기 
# 결과
$a
[1] 2

$c
[1] 5

 

< sapply()

Sapply(x, fun, 추가인자)

sapply(x, fun, 추가인자) # x : 배열, 리스트, 표현식 fun : 적용할 함수 / 결과를 행렬, 벡터 등의 데이터 타입으로 반환

sapply(iris[,1:4], mean)
Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
    5.843333     3.057333     3.758000     1.199333 
    
class(sapply(iris[,1:4], mean))
[1] "numeric"

x = sapply(iris[,1:4], mean)
as.data.frame(x)
                    x
Sepal.Length 5.843333
Sepal.Width  3.057333
Petal.Length 3.758000
Petal.Width  1.199333

 

< tapply()

tapply(x, index, fun) 

tapply(x, index, fun) # x: 배열 index : 데이터를 그루브로 묶을 색인, factor를 지정해야 하며, factor가 아닐 때에는 자동변환 
# *** 그룹핑의 기준을 나타내는 index
# -> 꼭 factor 형태여야 한다. 
# -> ex. 성별, 상중하 // 명확한 구분히 가능한 요인 / factor가 아니라면 변환시켜주기 

# iris 데이터들에 대해 species 별 Sepal.Length의 평균 구하기
# Species를 기준으로 그룹핑하여 각각의 Sepal.Length를 구해줘 
tapply(iris$Sepal.Length, iris$Species, mean)
    setosa versicolor  virginica 
     5.006      5.936      6.588 

 

< mapply()

mapply(fun, 적용할 인자)

mapply(fun, 적용할 인자) # fun : 적용할 함수, 여러개 벡터, 리스트를 인자로 해서 함수 반복적 적용 

# rnorm()을 다음 세가지 조합에 대해 호출할 때 (rnorm(n, mean, sd) 
# n - 1 2 3 / mean - 0 10 100 / sd - 1 1 1
mapply(rnorm, c(1,2,3), c(0,10,100), c(1,1,1))
# 결과 (결과값은 리스트)
[[1]]
[1] 0.9656959

[[2]]
[1] 10.082689  7.941112

[[3]]
[1]  99.36990 100.42345  98.46779

 

 

# 데이터를 그룹으로 묶은 후 함수 호출 

 

< doBy package >  install.packages("doBy") / library(doBy)

 

- summaryBy : 데이터 프레임을 컬럼값에 따라 그룹으로 묶은 후 요약 값 계산 / ~ 에 의해 분류한 후 분류 각각에 대해서 summary 해줘!

# Species에 따라서 Sepal의 Width와 Sepal의 Length 정보에 대해 summary 해줘! 
summary(Sepal.Width + Sepal.Length ~ Species, iris)
# '~' 다음에 나오는 단어(Species) : Species 값에 의해 그룹으로 묶기 
# '~' 이전에 나오는 단어(Sepal.Width+Sepal.Length) : 이 부분에 대해서 summary 해줘! 

     Species Sepal.Width.mean Sepal.Length.mean
1     setosa            3.428             5.006
2 versicolor            2.770             5.936
3  virginica            2.974             6.588

 

- orderBy() : 지정된 컬럼값에 따라 데이터 프레임을 정렬

 

order(iris$Sepal.Width) # 기준없이 순서대로 
# 결과 
 [1]  61  63  69 120  42  54  88  94  58  81  82  70  73  90  99 107 109 114 147  80  91
 [22]  93 119 135  60  68  83  84  95 102 112 124 143  55  56  72  74  77 100 115 122 123
 [43] 127 129 131 133 134   9  59  64  65  75  79  97  98 104 108   2  13  14  26  39  46
 [64]  62  67  76  78  85  89  92  96 103 105 106 113 117 128 130 136 139 146 148 150   4
 [85]  10  31  35  53  66  87 138 140 141 142   3  30  36  43  48  51  52  71 111 116 121
[106] 126 144  24  50  57 101 125 145   7   8  12  21  25  27  29  32  40  86 137 149   1
[127]  18  28  37  41  44   5  23  38 110  11  22  49  19  20  45  47 118 132   6  17  15
[148]  33  34  16

orderBy(~Sepal.Width, iris) # iris 데이터에 대해서 Sepal.Width를 기준으로 하여 전체를 모두 오름차순 정렬('~' 앞에 아무것도 쓰지 않았으니 전체 정렬)
# 결과 
    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
61           5.0         2.0          3.5         1.0 versicolor
63           6.0         2.2          4.0         1.0 versicolor
69           6.2         2.2          4.5         1.5 versicolor
120          6.0         2.2          5.0         1.5  virginica
42           4.5         2.3          1.3         0.3     setosa
54           5.5         2.3          4.0         1.3 versicolor
88           6.3         2.3          4.4         1.3 versicolor
94           5.0         2.3          3.3         1.0 versicolor
58           4.9         2.4          3.3         1.0 versicolor
81           5.5         2.4          3.8         1.1 versicolor
82           5.5         2.4          3.7         1.0 versicolor
70           5.6         2.5          3.9         1.1 versicolor
73           6.3         2.5          4.9         1.5 versicolor
90           5.5         2.5          4.0         1.3 versicolor
99           5.1         2.5          3.0         1.1 versicolor

 

- sampleBy() : 데이터프레임을 컬럼값에 따라 그룹으로 묶은 후 sample 추출

# *** 학습한 것 vs 테스트 결과의 정확도 확인할 때 사용하는 함수
# 각 Species 별로 모든 내용을 다 샘플해달라. 그때 샘플하는 뷰(fraction)을 0.1로 설정해달라. 
# = iris 데이터에서 각 Species 별로 10%의 데이터를 5개씩 추출
sampleBy(~Species, frac = 0.1, data = iris)
# 결과
              Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
setosa.5               5.0         3.6          1.4         0.2     setosa
setosa.34              5.5         4.2          1.4         0.2     setosa
setosa.35              4.9         3.1          1.5         0.2     setosa
setosa.40              5.1         3.4          1.5         0.2     setosa
setosa.47              5.1         3.8          1.6         0.2     setosa
versicolor.55          6.5         2.8          4.6         1.5 versicolor
versicolor.72          6.1         2.8          4.0         1.3 versicolor
versicolor.75          6.4         2.9          4.3         1.3 versicolor
versicolor.84          6.0         2.7          5.1         1.6 versicolor
versicolor.87          6.7         3.1          4.7         1.5 versicolor
virginica.108          7.3         2.9          6.3         1.8  virginica
virginica.111          6.5         3.2          5.1         2.0  virginica
virginica.125          6.7         3.3          5.7         2.1  virginica
virginica.128          6.1         3.0          4.9         1.8  virginica
virginica.142          6.9         3.1          5.1         2.3  virginica

 

 

# 데이터 분리 및 병합 

 

- split() : 주어진 조건에 따라 데이터를 분리한다. / split(데이터, 분리기준)

# 종 별로 분리 
split(iris, iris$Species)
$setosa
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1           5.1         3.5          1.4         0.2  setosa
2           4.9         3.0          1.4         0.2  setosa
... 
50          5.0         3.3          1.4         0.2  setosa

$versicolor
    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
51           7.0         3.2          4.7         1.4 versicolor
52           6.4         3.2          4.5         1.5 versicolor
...
100          5.7         2.8          4.1         1.3 versicolor

$virginica
    Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
101          6.3         3.3          6.0         2.5 virginica
102          5.8         2.7          5.1         1.9 virginica


#*** iris 데이터를 iris$Species에 따라 분리하고, 그 결과를 리스트에 저장 
# 커다란 데이터셋을 조건에 따라 분리 후 원래의 데이터셋에 리스트형태로 분리된 것들을 모아놓은 형태 

 

 

- subset() : 주어진 조건을 만족하는 데이터를 선택한다. 선택 후 부분집합으로 바로 구성함.

                  그 부분만 분리해서 별도의 데이터셋으로 만드는 데에 사용됨. 

subset(iris, Species=="setosa")
# iris 데이터 중 조건을 만족하는 특정 부분만 취합하여 반환 : setosa만 추출 

 

- merge() : 데이터를 공통된 값에 기준해 병합한다. (값의 순서가 바뀌어도 같은 값을 판단하여 값을 구분한다.) 

x = data.frame(name=c("a","b","c"), math=c(1,2,3))
y = data.frame(name=c("c","b","a"), english=c(4,5,6))
merge(x,y)
  name math english
1    a    1       6
2    b    2       5
3    c    3       4
# 알아서 name 값을 기준으로 math, english 값을 구분해 넣어준다. 

 

 

# 데이터 프레임 컬럼 접근

 

- with() : 코드블록 안에서 필드 이름만으로 데이터를 곧바로 접근할 수 있도록 함 

- within() : with()와 동일한 기능을 제공하지만, 데이터에 저장된 값을 손쉽게 변경하는 기능 제공 

- attach() : attatch() 이후 코드에서는 필드 이름만으로 데이터를 곧바로 접근할 수 있도록 함 

- detach() : attach()의 반대 역할로 detach() 이후 코드에서 더이상 필드 이름으로 데이터를 곧바로 접근할 수 없도록 함 

Sepal.Width
# -> Error

# 곧바로 접근 가능하도록
attach(irisr)
head(Sepal.Width)
[1] 3.5 3.0 3.2 3.1 3.6 3.9
# 이제 곧바로 접근 못해!

detach(iris)
Sepal.Width
# -> Error

 

III. R 데이터 조작, 처리, 가공 : dplyr packages

 

# dplyr package

- 데이터 전처리 : 분석에 적합하게 데이터를 가공하는 작업 

- 일부 추출, 종류별로 나누기, 여러 데이터 합치기 등의 작업 수행 

 

# < 함수 목록 > 
filter() # 행 추출 
select() # 열 추출 
arrange() # 정렬
mutate() # 변수 추가 
summarize() # 통계치 산출 
group_by() # 집단별로 나누기 
left_join() # 데이터 합치기 (열)
bind_rows() # 데이터 합치기 (행)
# pipe opearator 
%>% # 왼쪽의 것들을 오른쪽으로 그대로 흘려보냄 ~ 

 

 

- 데이터 가공 : [1] 추출 

1. 조건에 맞는 데이터만 추출 (행)

# exam 중 1반인 행만 추출하기
exam %>% filter(class==1)
exam %>% filter(class==1)
exam %>% filter(class!=1)
exam %>% filter(math>50)
... 

 

 

- 데이터 가공 : [2] 변수 추출

2. 조건에 맞는 변수만 추출 (열)

# 반, 영어 컬럼 추출하기
exam %>% select(class, English)
# english 컬럼만 제외하고 모든 컬럼 추출하기
exam %>% select(-English)
# 1반 학생의 영어 점수 추출 
exam %>% filter(class==1) %>% select(english)

 

- 데이터 가공 : [3] 정렬

3. 정렬하기 : arrange()

# exam 데이터를 math 기준으로 오름차순 정렬
exam %>% arrange(math)
# exam 데이터를 class(내림차순)우선정렬 후 math(오름차순) 기준으로 정렬
exam %>% arrange(class, desc(math))