데이터분석 전문가(ADP)를 위한 R프로그래밍 기초편4

1. 벡터

 

벡터의 원소들은 동질적

 

한 벡터의 모든 원소는 같은 자료형 또는 같은 모드(mode)를 가진다.

 

예를 들어 문자형과 수치형을 넣으면 모두 문자형으로 통일된다

 

> v <- c('yun',13,22

> v
[1] "yun" "13"  "22"

 

벡터는 위치로 indexing가능

 

v[2]는 v의 2번째 원소

 

벡터는 인덱스를 통해 여러 개의 원소로 구성된 하위 벡터를 반환할 수 있다

 

v[c(2,3)]은 v벡터의 2번째, 3번째 원소로 구성된 하위벡터

 

인덱스에 -를 붙이면 해당 번호는 제외한 나머지 번호의 원소를 가져옴

 

v[-c(2,3)]은 2,3번째 값을 제외한 하위벡터

 

> v <- c(33,21,42,32,5,4,432,21)

> v[2]
[1] 21

> v[c(2,3)]
[1] 21 42

> v[-c(2,3)]
[1]  33  32   5   4 432  21

 

벡터의 원소들도 이름을 가질 수 있다

 

> v <- c(10,20,30)

> names(v) <- c('Moe', 'Larry', 'Curly')

> v['Larry']

Larry 
   20 
   
> v
  Moe Larry Curly 
   10    20    30

 

주어진 벡터에 데이터를 추가할 수도 있다

 

v <- c(v, <추가할 원소>)

 

v[length(v)+1] <- <추가할 원소>

 

v <- append(vec, <추가할 값>, after=n)

 

after=n은 n번째 다음인 n+1번째에 <추가할값>을 넣겠다는 의미

> v <- c(1,2,3,4,5,6)

> v <- c(v,7)
> v
[1] 1 2 3 4 5 6 7

> v[length(v)+1] <- 8
> v
[1] 1 2 3 4 5 6 7 8

> v <- append(v, 9, after=length(v))
> v
[1] 1 2 3 4 5 6 7 8 9

> v <- append(v,10, after=3)
> v
 [1]  1  2  3 10  4  5  6  7  8  9

 

stack함수를 이용하여 여러 벡터를 하나의 벡터로 만들 수 있다

 

> comb <- stack(list(v1=v1,v2=v2,v3=v3))

> comb
  values ind
1      1  v1
2      2  v1
3      3  v1
4      4  v2
5      5  v2
6      6  v2
7      7  v3
8      8  v3
9      9  v3

> comb$values
[1] 1 2 3 4 5 6 7 8 9

 

comb$values해야 합쳐진 벡터가 나오는디?

 

2. 리스트

 

리스트의 원소는 이질적이다

 

숫자, 문자, 함수등 여러 자료형의 원소들이 포함될 수 있다

 

list(x,y,z)

 

list(name1=x, name2=y, name3=z...) 등으로 생성가능

 

> a <- list('yun',13,22)
> a
[[1]]
[1] "yun"

[[2]]
[1] 13

[[3]]
[1] 22

> a <- list(name='yun', number=1, num2=3)
> a
$name
[1] "yun"

$number
[1] 1

$num2
[1] 3

 

리스트는 위치로 인덱스된다.

 

L[[2]]는 L리스트의 2번째 원소

 

리스트에서도 하위 리스트를 추출할 수 있다

 

L[c(2,3)]은 L리스트의 2번째, 3번째 원소로 이루어진 하위 리스트

 

> a[[2]]

[1] 13

> a[c(2,3)]

[[1]]
[1] 13

[[2]]
[1] 22

 

리스트의 원소들도 이름을 가질 수 있다

 

L[['Moe']]와 L$Moe는 둘다 'Moe'라는 이름의 원소를 지칭 한다

 

> names(a) <- c('Moe','Larry','Curly')

> a[['Moe']]

[1] "yun"

> a$Moe

[1] "yun"

 

인덱싱에 NULL을 넣으면 해당 인덱싱 번호의 원소를 제거할 수 있다

 

> a <- list(name='yun', number=1, num2=3)
> a
$name
[1] "yun"

$number
[1] 1

$num2
[1] 3

> a[['name']] <- NULL
> a
$number
[1] 1

$num2
[1] 3

 

NA를 넣으면 NULL원소가 들어간다

 

그리고 이 NA원소 인덱싱에 NULL을 넣으면 NA원소가 제거된다

 

> a
$number
[1] 1

$num2
[1] 3

> a[['name']] <- NA
> a
$number
[1] 1

$num2
[1] 3

$name
[1] NA

> a[is.na(a)] <- NULL
> a
$number
[1] 1

$num2
[1] 3

3. 자료형

 

R에서는 자료형을 mode라고 칭한다

 

mode()함수를 이용해 여러가지 객체의 자료형을 확인할 수 있다

 

숫자, 숫자 벡터, factor는 수치형(numeric)

 

> mode(3.1415)
[1] "numeric"

> mode(c(2,3,4,5.5))
[1] "numeric"

> mode(factor(c('A','B','C')))
[1] "numeric"

 

문자열, 문자열벡터는 문자형(character)

 

> mode('Tom')
[1] "character"

> mode(c('Tom','yoon','kim'))
[1] "character"

 

리스트와 데이터프레임은 리스트(list)

 

> mode(list('tom','yoon','kim'))
[1] "list"

> mode(data.frame(x=1:3,y=c('tom','yoon','kim')))
[1] "list"

 

함수는 함수(function)

 

> mode(print)
[1] "function"

 

factor가 수치형이고 데이터프레임이 리스트라는것 혼동하기 쉬우니 기억해야

 

4. 데이터프레임

 

강력하고 유연한 구조

 

SAS의 데이터셋을 모방해서 만들어진다

 

행과 열로 이루어지지만 행렬이라기보다는 리스트라고 볼 수 있다

 

표 형태의 데이터구조이고 각 열은 서로 다른 데이터 형식을 가질 수 있다

 

열은 이름이 있어야 한다

 

열의 길이는 서로 동일해야한다

 

데이터 프레임의 리스트의 원소는 벡터 또는 factor이고 이는 데이터 프레임의 열이 된다

 

data.frame( <열1 이름> = 열1 값, <열2 이름> = 열2 값, ........, row.names=)

 

> data.frame(number=1:3,name=c('tom','yoon','kim'))
  number name
1      1  tom
2      2 yoon
3      3  kim

> data.frame(number=1:3,name=c('tom','yoon','kim'),row.names=c(3,4,5))
  number name
3      1  tom
4      2 yoon
5      3  kim

 

row.names=은 index의 값들을 지정해준다

 

인덱싱으로 원소에 접근할 수 있다

 

a[1], a[[1]], a['1열 이름'], a[['1열 이름']], a$1열 이름 은 1열을 추출

 

a[1]은 데이터프레임으로 추출하지만

 

a[[1]]은 벡터로 추출함

 

행을 추출할려면 a[행,열] 방식으로 추출한다

 

a[1,]은 1행을 추출하고

 

a[,2]는 2열을 추출한다

 

a[1,2]는 1행 2열을 추출한다

 

> a <- data.frame(number=1:3,name=c('tom','yoon','kim'))

> a[1]
  number
1      1
2      2
3      3

> mode(a[1])
[1] "list"

> a[[1]]           
[1] 1 2 3

> mode(a[[1]])
[1] "numeric"

> a['name']
  name
1  tom
2 yoon
3  kim

> a[['name']]
[1] "tom"  "yoon" "kim" 

> a$name
[1] "tom"  "yoon" "kim" 

> a[1,]
  number name
1      1  tom

> a[1,1]
[1] 1

> a[1,2]
[1] "tom"

> a[,2]
[1] "tom"  "yoon" "kim" 

> a[[1,]]
Error in `[[.data.frame`(a, 1, ) : 
  argument "..2" is missing, with no default

 

 

5. 스칼라(scalars)

 

R에서는 원소가 하나인 벡터로 인식하고 처리함

 

> pi
[1] 3.141593

> length(pi)
[1] 1

 

6. 행렬(matrix)

 

R에서는 차원을 가진 벡터로 인식함

 

벡터에 dim()을 2차원 c(a,b)로 주면 a*b 행렬이 된다

 

혹은 matrix(data, 행, 열)을 넣으면 data를 행렬로 만든다

 

단순히 숫자만을 matrix로 만들면 행,열 크기에 맞도록 동일한 숫자를 집어넣는다

 

소셜네트워크분석, 텍스트마이닝 등에 활용

 

> a <- 1:9

> dim(a) <- c(3,3)

> a
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

> a <- matrix(1:10, 2,4)
Warning message:
In matrix(1:10, 2, 4) :
  data length [10] is not a sub-multiple or multiple of the number of columns [4]
  
> a
     [,1] [,2] [,3] [,4]
[1,]    1    3    5    7
[2,]    2    4    6    8

> a <- matrix(1:10, 2,5)
> a
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    3    5    7    9
[2,]    2    4    6    8   10

> a <- matrix(2, 1,3)
> a
     [,1] [,2] [,3]
[1,]    2    2    2

 

dim(a)하면 행렬 a의 차원

 

diag(a)하면 a의 대각원소의 값을 반환

 

t(a)하면 a의 전치행렬

 

solve(a)하면 a의 역행렬을 출력

 

> a <- matrix(c(3,2,5,3,1,2,3,9,-1),3,3)
> a
     [,1] [,2] [,3]
[1,]    3    3    3
[2,]    2    1    9
[3,]    5    2   -1

> dim(a)

[1] 3 3

> diag(a)

[1]  3  1 -1

> t(a)
     [,1] [,2] [,3]
[1,]    3    2    5
[2,]    3    1    2
[3,]    3    9   -1

> solve(a)
            [,1]       [,2]        [,3]
[1,] -0.23456790  0.1111111  0.29629630
[2,]  0.58024691 -0.2222222 -0.25925926
[3,] -0.01234568  0.1111111 -0.03703704

 

%*%는 행렬곱 연산

 

*은 행렬과 상수의 곱에만 가능

 

> a <- matrix(c(3,2,5,3,1,2,3,9,-1),3,3)

> b <- matrix(c(5,-2,3,5,4,3,2,7,5,-2,9,12),3,4)

> a%*%b
     [,1] [,2] [,3] [,4]
[1,]   18   36   42   57
[2,]   35   41   56  113
[3,]   18   30   19   -4

> a
     [,1] [,2] [,3]
[1,]    3    3    3
[2,]    2    1    9
[3,]    5    2   -1

> a*3
     [,1] [,2] [,3]
[1,]    9    9    9
[2,]    6    3   27
[3,]   15    6   -3

 

덧셈,뺄셈은 그냥 +,-로 가능

 

당연하지만 행렬끼리 덧셈뺄셈은 차원이 같아야함

 

> a
     [,1] [,2] [,3]
[1,]    3    3    3
[2,]    2    1    9
[3,]    5    2   -1

> a+3
     [,1] [,2] [,3]
[1,]    6    6    6
[2,]    5    4   12
[3,]    8    5    2

> a-3
     [,1] [,2] [,3]
[1,]    0    0    0
[2,]   -1   -2    6
[3,]    2   -1   -4

> b
     [,1] [,2] [,3] [,4]
[1,]    5    5    2   -2
[2,]   -2    4    7    9
[3,]    3    3    5   12

> a+b
Error in a + b : non-conformable arrays

> b <- matrix(c(5,-2,3,5,4,3,2,7,5),3,3)
> a+b
     [,1] [,2] [,3]
[1,]    8    8    5
[2,]    0    5   16
[3,]    8    5    4

 

행과 열에 이름을 붙일 수 있다

 

rownames(a) <- c()

 

colnames(a) <- c()

 

> a <- matrix(c(3,2,5,3,1,2,3,9,-1),3,3)

> a
     [,1] [,2] [,3]
[1,]    3    3    3
[2,]    2    1    9
[3,]    5    2   -1

> colnames(a) <- c('A','B','C')
> rownames(a) <- c('D','E','F')

> a
  A B  C
D 3 3  3
E 2 1  9
F 5 2 -1

 

행렬의 인덱싱은 a[행,열] 방식으로

 

a[1,]은 1행

 

a[,2]는 2열

 

a[1,2]는 1행 2열 원소

 

> a <- matrix(c(3,2,5,3,1,2,3,9,-1),3,3)
> a
     [,1] [,2] [,3]
[1,]    3    3    3
[2,]    2    1    9
[3,]    5    2   -1

> a[1,]
[1] 3 3 3

> a[,2]
[1] 3 1 2

> a[1,2]
[1] 3

 

 

7. 배열(array)

 

행렬이 3차원 이상으로 확장된 형태

 

주어진 벡터에 더 많은 차원을 부여하여 생성할 수 있다

 

> a <- 1:12

> dim(a) <- c(2,3,2)

> a
, , 1

     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6

, , 2

     [,1] [,2] [,3]
[1,]    7    9   11
[2,]    8   10   12

 

8. 요인(factor)

 

범주형 변수, 집단분류 용도로 사용하는 벡터의 일종

 

factor(v, levels=)를 이용하여 생성, v는 (문자열 또는 정수)벡터

 

levels는 사용자가 직접 level을 지정해줌

 

factor에 들어간 고유한 값(unique value)들을 level이라고 부름

 

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

> a
[1] a b c
Levels: a b c

> a <- factor(c('a','b','c','a','b','d'))

> a
[1] a b c a b d
Levels: a b c d

 

9. 재활용규칙

 

파이썬의 broadcasting

 

길이가 서로 다른 두 벡터에 대해 연산을 할 때 R은 짧은 벡터의 처음으로 돌아가 연산이 끝날때까지 원소들을 재활용

 

> a <- seq(1,6)
> a
[1] 1 2 3 4 5 6

> b <- seq(7,9)
> b
[1] 7 8 9

> a+b
[1]  8 10 12 11 13 15

> cbind(a,b)
     a b
[1,] 1 7
[2,] 2 8
[3,] 3 9
[4,] 4 7
[5,] 5 8
[6,] 6 9

 

위와 같이 a,b를 더하는데 길이가 짧은 b의 원소를 a의 길이에 맞도록 7,8,9를 다 쓰면

 

처음부터 재활용해서 덧셈을 해준다

 

a가 b의 길이의 배수가 아니더라도 가능은함

 

> b <- seq(7,10)
> b
[1]  7  8  9 10

> cbind(a,b)
     a  b
[1,] 1  7
[2,] 2  8
[3,] 3  9
[4,] 4 10
[5,] 5  7
[6,] 6  8
Warning message:
In cbind(a, b) :
  number of rows of result is not a multiple of vector length (arg 2)
  
> a+b
[1]  8 10 12 14 12 14

Warning message:
In a + b : longer object length is not a multiple of shorter object length

7,8,9,10을 모두 쓰면 다시 처음부터 돌아가서 7,8을 사용함

 

참고

 

https://lightblog.tistory.com/13

 

[R.아르] 특정 조건을 만족하는 행만 추출하기

2016/08/30 - [R] - [R.아르] R 행,열 삭제 의 연장선상에서, 꼭 '몇 번째' 행만 뽑을 수 있는 것은 아니다. 특정 조건을 만족하는 행도 추출할 수 있다. 다음과 같은 x가 있다고 하자. 여기서 var 가 70 이

lightblog.tistory.com

 

 

TAGS.

Comments