R이 통계분석 툴이자 그래픽을 위한 훌륭한 툴이면서도, 동시에 프로그래밍 언어(programming language)로서도 매우 훌륭하답니다.  반복적인 작업(Loop process)을 해야 하는 경우나, 분석가가 알고리즘을 만들어서 자동화할 수 있는 사용자 정의 함수(User defined function) 를 잘 사용한다면 소위 말하는 시간 잡아먹는 노가다를 컴퓨터에게 대신 시킬 수 있게 됩니다. 

 

손발이 편하고 싶고, 귀한 시간을 아끼고 싶다면 R 프로그래밍에 대해 익혀두는게 유용할 것입니다.  게다가, R이 데이터 변환/처리/분석/그래프 까지 두루 섭렵하고 있다보니 "데이터 기반의 프로그래밍"이 필요한 일이라면 R이 제격이라고 하겠습니다.

 

이번 포스팅에서는 for()와 while() 함수를 사용하여 반복 연산 프로그래밍 (Loop process programming) 하는 방법을 몇 개 예를 들어 소개하겠습니다.

 

 

[ Loop Process Diagram ]

 

 

 

 

(1) y= 10 + 5*x 함수에 x를 1부터 10까지 1씩 더해가면서 연산하고 y값을 순차적으로 프린트

     : for (var in seq) {expression}

 

> # x 1:10, y = 10 + 5*x
> for ( x in 1:10) {
+   y = 10 + 5*x
+   print(y)
+ }
[1] 15
[1] 20
[1] 25
[1] 30
[1] 35
[1] 40
[1] 45
[1] 50
[1] 55
[1] 60 

 

 

(2) 1~10까지의 1씩 늘려가면서 누적합 구하고, 순차적으로 프린트하기

    : for (var in seq) {expression}

 

 
> # 1~10까지 누적합 구하기 (cummulative sum by for) : for (var in seq) { expression }
> y <- 0
> for(i in 1:10) {
+      y = y + i
+      cat("cummulative summation from 0 to ", i, " is ", y, "\n", sep="")
+    }
cummulative summation from 0 to 1 is 1
cummulative summation from 0 to 2 is 3
cummulative summation from 0 to 3 is 6
cummulative summation from 0 to 4 is 10
cummulative summation from 0 to 5 is 15
cummulative summation from 0 to 6 is 21
cummulative summation from 0 to 7 is 28
cummulative summation from 0 to 8 is 36
cummulative summation from 0 to 9 is 45
cummulative summation from 0 to 10 is 55
 

 

참고로, cat 은 텍스트를 받아다가 콘솔에 프린트해주는 기능을 합니다.

"\n" 은 줄바꿈 설정하는 파라미터입니다.

sep="" 는 cat() 함수 안에 큰따옴표로 들어가 있는 텍스트 문자열 혹은 'i', 'z' 객체를 연결할 때 구분자를 지정해주는 것입니다. sep="" 이므로 아무것도 없이 그냥 붙여서 연결시키라는 뜻이구요, 만약 sep="__" 라고 under-bar 2개로 지정해주면 첫번째 줄이

cummulative summation from 0 to __1__ is __1

처럼 프린트 되었을 것입니다.

 

 

 

(3) 1~10까지의 1씩 늘려가면서 누적합 구하고, 순차적으로 프린트하기

    : while (condition) {expression}

 

while() 문은 조건을 걸고 싶거나 반복회수를 미리 파악하기 어려운 경우에 사용하면 유용합니다.

 

 
> # 1~10까지 누적합 구하기 (cummlative sum by while) : while(condition) { expression }
> z <- 0
> i <- 1
> while( i <= 10) {
+      z = z + i
+      cat("cummulative summation from 0 to ", i, " is ", z, "\n", sep="") 
+      i = i + 1
+    }
cummulative summation from 0 to 1 is 1
cummulative summation from 0 to 2 is 3
cummulative summation from 0 to 3 is 6
cummulative summation from 0 to 4 is 10
cummulative summation from 0 to 5 is 15
cummulative summation from 0 to 6 is 21
cummulative summation from 0 to 7 is 28
cummulative summation from 0 to 8 is 36
cummulative summation from 0 to 9 is 45
cummulative summation from 0 to 10 is 55
 

 

 

 


 

 

예를 들어, 1부터 시작해서 1씩 늘려가면서 3을 더해가는 것(y = y + 3)을 반복하는데, 단 5 이하일 때까지만 반복시키는 조건이 있을 때,

 - while(condition)

 - while(TRUE/FALSE) { if () break }

 - repeat { if () break }

의 3가지 방법을 알아보겠습니다.  아래의 (4) ~ (6)번 프로그래밍 예제는 로직과 결과가 동일합니다.

 

(4) while(condition)

 

> # while(condition) => stop
> i <- 1
> while( i <= 5 ) {
+   i <- i+3
+ }
> 
> i
[1] 7 

 

 

 

(5) while(TRUE/FALSE) { if () break }

 

> # while(TRUE/FALSE) { if () break } => stop
> j <- 1
> while(TRUE) {
+   j <- j+3
+   if (j > 5) break
+ }
> 
> j
[1] 7

 

처음에 j <- 1로 할당되었습니다. 

그 다음에 while() 문으로 넘어가서요, j <- j+3 이므로 j <- 1+3 가 되어서 j에 4가 새로 할당(덮어쓰기)이 되었습니다.  if (j > 5) break 인데요, 여기서 j는 4이므로 if (j > 5) 조건에서 FALSE 가 됩니다. 따라서 break하지 않고 loop 를 계속 돌게 됩니다(not break, but continue loop). 

그럼 다시 j <- j+3 으로 돌아가서 다시 연산을 수행합니다. 방금 전 연산에서 j가 4로 재할당 되었었지요? 그러므로 j+3 = 4+3 = 7로서 j에 7이 재할당 (덮어쓰기) 됩니다.

if (j > 5) 조건에서 if (7 > 5) 로서 TRUE 가 되었으므로 break 하게 됩니다.

j 를 프린트해보면 '7'이 됩니다.

 

 

 

(6) repeat { if () break }

 

> # repeat { if () break } => stop > k <- 1 > repeat { + k <- k+3 + if (k > 5) break + } > > k [1] 7

 

 

위의 (5)번, (6)번 예에서 보면 while 문에는 TRUE/FALSE 의 불리언 상태값이 있습니다만, repeat 문에는 불리언 상태값 없이 break 를 사용해서 조건을 만족하면 반복을 중지시키는 차이점이 있습니다.

 

 

 


 

아래의 프로그램 예는 repeat 함수를 이용해서 factorial(i) 값이 1,000,000,000,000 보다 작을 때까지는 계산 순차적으로 1씩 i를 증가시켜가면서 계산을 하고 프린트를 하다가, 1조보다 커지면 stop하라는 명령문입니다.

 

 
> i <- 1
> repeat {
+   factorial_value <- factorial(i)
+   cat("factorial(", i, ") = ", factorial_value, "\n", sep="")
+   if (factorial_value > 1000000000000) break
+   i <- i+1
+ }
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
factorial(5) = 120
factorial(6) = 720
factorial(7) = 5040
factorial(8) = 40320
factorial(9) = 362880
factorial(10) = 3628800
factorial(11) = 39916800
factorial(12) = 479001600
factorial(13) = 6227020800
factorial(14) = 87178291200
factorial(15) = 1.307674e+12

 

 

 

 

factorial(i) 값이 '0'이 100개 붙은 값(우리나라말로 이걸 명칭하는 단위가 없죠? 어마무시 큰 수? ^^')보다 작으면 계속 i 값을 1씩 증가시키면서 계산하다가, '0'이 100개 붙은 값보다 커지면 stop 하라는 명령문은 아래와 같습니다.

 

> i <- 1
> repeat {
+   factorial_value <- factorial(i)
+   cat("factorial(", i, ") = ", factorial_value, "\n", sep="")
+   if (factorial_value > 1e+100) break
+   i <- i+1
+ }
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
factorial(5) = 120
factorial(6) = 720
factorial(7) = 5040
factorial(8) = 40320
factorial(9) = 362880
factorial(10) = 3628800
factorial(11) = 39916800
factorial(12) = 479001600
factorial(13) = 6227020800
factorial(14) = 87178291200
factorial(15) = 1.307674e+12
factorial(16) = 2.092279e+13
factorial(17) = 3.556874e+14
factorial(18) = 6.402374e+15
factorial(19) = 1.216451e+17
factorial(20) = 2.432902e+18
factorial(21) = 5.109094e+19
factorial(22) = 1.124001e+21
factorial(23) = 2.585202e+22
factorial(24) = 6.204484e+23
factorial(25) = 1.551121e+25
factorial(26) = 4.032915e+26
factorial(27) = 1.088887e+28
factorial(28) = 3.048883e+29
factorial(29) = 8.841762e+30
factorial(30) = 2.652529e+32
factorial(31) = 8.222839e+33
factorial(32) = 2.631308e+35
factorial(33) = 8.683318e+36
factorial(34) = 2.952328e+38
factorial(35) = 1.033315e+40
factorial(36) = 3.719933e+41
factorial(37) = 1.376375e+43
factorial(38) = 5.230226e+44
factorial(39) = 2.039788e+46
factorial(40) = 8.159153e+47
factorial(41) = 3.345253e+49
factorial(42) = 1.405006e+51
factorial(43) = 6.041526e+52
factorial(44) = 2.658272e+54
factorial(45) = 1.196222e+56
factorial(46) = 5.502622e+57
factorial(47) = 2.586232e+59
factorial(48) = 1.241392e+61
factorial(49) = 6.082819e+62
factorial(50) = 3.041409e+64
factorial(51) = 1.551119e+66
factorial(52) = 8.065818e+67
factorial(53) = 4.274883e+69
factorial(54) = 2.308437e+71
factorial(55) = 1.26964e+73
factorial(56) = 7.109986e+74
factorial(57) = 4.052692e+76
factorial(58) = 2.350561e+78
factorial(59) = 1.386831e+80
factorial(60) = 8.320987e+81
factorial(61) = 5.075802e+83
factorial(62) = 3.146997e+85
factorial(63) = 1.982608e+87
factorial(64) = 1.268869e+89
factorial(65) = 8.247651e+90
factorial(66) = 5.443449e+92
factorial(67) = 3.647111e+94
factorial(68) = 2.480036e+96
factorial(69) = 1.711225e+98
factorial(70) = 1.197857e+100

 

 

많은 도움 되었기를 바랍니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡' 단추를 꾸욱 눌러주세요.^^

 

 

Posted by R Friend R_Friend