R으로 짜는 구구단

어제 쓴 구구단 글 중에 R로 구구단 짠 것 중에 이런 코드가 있었는데, 약간 보충설명.

#!r!#
matrix(rep(1:9, 8), 8, 9, byrow=T) *
  matrix(rep(2:9, rep(9, 8)), 8, 9, byrow=T)

R이란 언어는 통계에 특화된 프로그래밍 언어인데 기본 단위가 벡터로 이루어진다. 이 코드를 조금씩 나눠서 보게되면, 우선 앞부분의 1:9는 1부터 9까지의 백터를 만든다. 앞에 대괄호로 둘러싼 부분은 해당하는 줄의 맨 앞의 요소가 몇 번째 요소인지를 나타낸다.

#!r!#
1:9

결과

#!plain_text!#
[1] 1 2 3 4 5 6 7 8 9

이 벡터를 감싸고있는 rep라는 함수는 repeat의 줄임말. 1:9를 8번 반복하라는 의미가 된다.

#!r!#
rep(1:9, 8)

결과

#!plain_text!#
[1] 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9
[37] 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9

이걸 다시 감싸고 있는 게 matrix 함수. 글자 그대로 행렬을 생성한다. 첫번째 인자로는 벡터를 집어넣고, 두번째 인자는 행수, 세번째 인자는 열수를 나타낸다.

#!r!#
matrix(rep(1:9, 8), 8, 9)

결과

#!plain_text!#
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,]    1    9    8    7    6    5    4    3    2
[2,]    2    1    9    8    7    6    5    4    3
[3,]    3    2    1    9    8    7    6    5    4
[4,]    4    3    2    1    9    8    7    6    5
[5,]    5    4    3    2    1    9    8    7    6
[6,]    6    5    4    3    2    1    9    8    7
[7,]    7    6    5    4    3    2    1    9    8
[8,]    8    7    6    5    4    3    2    1    9

결과 값을 보면 알겠지만, 위에서 1줄로 늘어져있던 벡터를 정해진 행과 열로 만들어준다. byrow 옵션에 TRUE (R에서는 다 대문자로 쳐야만 한다)를 주면 열방향이 아닌 행방향으로 차례차례 데이터를 집어넣어서 행렬을 만든다.

#!plain_text!#
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,]    1    2    3    4    5    6    7    8    9
[2,]    1    2    3    4    5    6    7    8    9
[3,]    1    2    3    4    5    6    7    8    9
[4,]    1    2    3    4    5    6    7    8    9
[5,]    1    2    3    4    5    6    7    8    9
[6,]    1    2    3    4    5    6    7    8    9
[7,]    1    2    3    4    5    6    7    8    9
[8,]    1    2    3    4    5    6    7    8    9

이게 위에서 본 첫번째 줄의 결과값.

아랫줄에선 rep(2:9, rep(9, 8))라는 부분이 좀 까다로운데, 두번째 인자는 하나의 값을 받으면 앞의 벡터를 몇 번 반복하는지를 의미하지만, 벡터를 받으면 조금 의미가 달라진다. 첫번째 인자와 두번째 인자의 벡터 길이가 같다고할 때, 두번째 인자의 첫번째 수치는 첫번째 인자의 첫번째 수치를 몇 번 반복할 지가 되고, 두번째 인자의 두번째 수치는 첫번째 인자의 두번째 수치를 몇 번 반복할 지가 되고....

하는 식이 된다. 따라서 위의 식을 평가하면.

#!plain_text!#
[1] 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5
[37] 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9

설명은 좀 애매한지만, 막상 결과값을 보면 2에서 9까지 9번씩 반복하라는 명령임을 알 수 있다. 이걸 행렬로 만든다.

#!r!#
matrix(rep(2:9, rep(9, 8)), 8, 9, byrow=T)

결과

#!plain_text!#
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,]    2    2    2    2    2    2    2    2    2
[2,]    3    3    3    3    3    3    3    3    3
[3,]    4    4    4    4    4    4    4    4    4
[4,]    5    5    5    5    5    5    5    5    5
[5,]    6    6    6    6    6    6    6    6    6
[6,]    7    7    7    7    7    7    7    7    7
[7,]    8    8    8    8    8    8    8    8    8
[8,]    9    9    9    9    9    9    9    9    9

이게 두번째 줄의 평가값이 된다.

그리고 마지막으로 첫번째 행렬 matrix(rep(1:9, 8), 8, 9, byrow=T)과 두번째 행렬 matrix(rep(2:9, rep(9, 8)), 8, 9, byrow=T)를 곱해주는데 연산자 *는 행렬곱이 아니라, 단순히 두 행렬에서 같은 위치의 값들을 곱해준다.

#!plain_text!#
    [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,]    2    4    6    8   10   12   14   16   18
[2,]    3    6    9   12   15   18   21   24   27
[3,]    4    8   12   16   20   24   28   32   36
[4,]    5   10   15   20   25   30   35   40   45
[5,]    6   12   18   24   30   36   42   48   54
[6,]    7   14   21   28   35   42   49   56   63
[7,]    8   16   24   32   40   48   56   64   72
[8,]    9   18   27   36   45   54   63   72   81

구구단 테이블 완성. R은 아무래도 문제 접근법이 완전히 다르기 때문에 딱 보고 와닿지가 않을 것 같아서 조금 덧붙여봤다.


Who am I?