조건문(condditional statement)

4-1 (기본 if-else 문)

job.type <- 'A'
if(job.type == 'B') {
  bonus <- 200          # 직무 유형이 B일 때 실행
} else {
  bonus <- 100          # 직무 유형이 B가 아닌 나머지 경우 실행
}
print(bonus)
## [1] 100

4-2 (else가 생략된 if 문)

job.type <- 'B'
bonus <- 100
if(job.type == 'A') {
  bonus <- 200            # 직무 유형이 B일 때 실행
}
print(bonus)
## [1] 100

4-3 (다중 if-else 문)

score <- 85

if (score > 90) {
  grade <- 'A' 
} else if (score > 80) {
  grade <- 'B' 
} else if (score > 70) {
  grade <- 'C' 
} else if (score > 60) {
  grade <- 'D' 
} else {
  grade <- 'F' 
}

print(grade)
## [1] "B"

4-4 (조건문에서 논리연산자의 사용)

a <- 10
b <- 20
if(a>5 & b>5) {         # and 사용
  print (a+b)
}
## [1] 30
if(a>5 | b>30) {        # or 사용
  print (a*b)
}
## [1] 200

4-5 (ifelse문: 변수 <- ifelse(조건문, TRUE일때 출력값, FALSE일때 출력값) )

a <- 10
b <- 20

if  (a>b) {
  c <- a
} else {
  c <- b
}
print(c) #20
## [1] 20
a <- 10
b <- 20

c <- ifelse(a>b, a, b)
print(c)
## [1] 20

%in%사용법

V1 <- 3
V2 <- 101
t <- c(1,2,3,4,5,6,7,8)
V1 %in% t
## [1] TRUE
V2 %in% t
## [1] FALSE
mtcars$cyl %in% 4 # 데이터프레임과의 사용법!
##  [1] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE
## [13] FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE
## [25] FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE

반복문 (Loops)

4-6 (기본 for문)

for(i in 1:5) {
  print('*')
}
## [1] "*"
## [1] "*"
## [1] "*"
## [1] "*"
## [1] "*"

4-7 (반복범위에 따른 반복변수의 값 변화)

for(i in 6:10) {
  print(i)
}
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10

4-8 (반복변수를 이용한 구구단 출력)

for(i in 1:9) {
  cat('2 *', i,'=', 2*i,'\n') # cat은 default로는 linefeed 출력이 안되는 관계로 \n추가 필요

}
## 2 * 1 = 2 
## 2 * 2 = 4 
## 2 * 3 = 6 
## 2 * 4 = 8 
## 2 * 5 = 10 
## 2 * 6 = 12 
## 2 * 7 = 14 
## 2 * 8 = 16 
## 2 * 9 = 18
for(i in 1:9) cat('2 *', i,'=', 2*i,'\n') # 한줄은 이렇게해도 됌
## 2 * 1 = 2 
## 2 * 2 = 4 
## 2 * 3 = 6 
## 2 * 4 = 8 
## 2 * 5 = 10 
## 2 * 6 = 12 
## 2 * 7 = 14 
## 2 * 8 = 16 
## 2 * 9 = 18
for(i in 1:9) {
  print(paste('2 *', i,'=', 2*i)) # loop안에서는 print문으로 감싸야 paste 결과 나타남 
}
## [1] "2 * 1 = 2"
## [1] "2 * 2 = 4"
## [1] "2 * 3 = 6"
## [1] "2 * 4 = 8"
## [1] "2 * 5 = 10"
## [1] "2 * 6 = 12"
## [1] "2 * 7 = 14"
## [1] "2 * 8 = 16"
## [1] "2 * 9 = 18"

4-9 (for문 안에서 if문 사용)

for(i in 1:20) {
  if(i%%2==0) {     # 짝수인지 확인
    print(i)
  }
}
## [1] 2
## [1] 4
## [1] 6
## [1] 8
## [1] 10
## [1] 12
## [1] 14
## [1] 16
## [1] 18
## [1] 20

4-10 (1~100 사이의 숫자의 합 출력)

sum <- 0
for(i in 1:100) {
  sum <- sum + i    # sum에 i 값을 누적
}
print(sum)
## [1] 5050

4-11 (iris에서 꽃잎의 길이에 따른 분류 작업)

norow <- nrow(iris)                               # iris의 행의 수
mylabel <- c( )                                   # 비어있는 벡터 선언
for(i in 1:norow) {
  if (iris$Petal.Length[i] <= 1.6) {              # 꽃잎의 길이에 따라 레이블 결정
    mylabel[i] <- 'L'
  } else if (iris$Petal.Length[i] >= 5.1) {
    mylabel[i] <- 'H'
  } else {
    mylabel[i] <- 'M'
  }
}
print(mylabel)                                    # 레이블 출력
##   [1] "L" "L" "L" "L" "L" "M" "L" "L" "L" "L" "L" "L" "L" "L" "L" "L" "L" "L"
##  [19] "M" "L" "M" "L" "L" "M" "M" "L" "L" "L" "L" "L" "L" "L" "L" "L" "L" "L"
##  [37] "L" "L" "L" "L" "L" "L" "L" "L" "M" "L" "L" "L" "L" "L" "M" "M" "M" "M"
##  [55] "M" "M" "M" "M" "M" "M" "M" "M" "M" "M" "M" "M" "M" "M" "M" "M" "M" "M"
##  [73] "M" "M" "M" "M" "M" "M" "M" "M" "M" "M" "M" "H" "M" "M" "M" "M" "M" "M"
##  [91] "M" "M" "M" "M" "M" "M" "M" "M" "M" "M" "H" "H" "H" "H" "H" "H" "M" "H"
## [109] "H" "H" "H" "H" "H" "M" "H" "H" "H" "H" "H" "M" "H" "M" "H" "M" "H" "H"
## [127] "M" "M" "H" "H" "H" "H" "H" "H" "H" "H" "H" "H" "M" "H" "H" "H" "H" "H"
## [145] "H" "H" "M" "H" "H" "H"
newds <- data.frame(iris$Petal.Length, mylabel)   # 꽃잎의 길이와 레이블 결합
head(newds)                                       # 새로운 데이터셋 내용 출력
##   iris.Petal.Length mylabel
## 1               1.4       L
## 2               1.4       L
## 3               1.3       L
## 4               1.5       L
## 5               1.4       L
## 6               1.7       M

4-12 (while 문)

sum <- 0
i <- 1
while(i <=100) {
  sum <- sum + i      # sum에 i 값을 누적
  i <- i + 1          # i 값을 1 증가시킴
}
print(sum)
## [1] 5050

4-13 (break)

sum <- 0
for(i in 1:10) {
  sum <- sum + i
  if (i>=5) break # break가 sum뒤에 있으므로, 5까지 더한후 break!
}
sum
## [1] 15

4-14 (next = java에서 continue기능!)

sum <- 0
for(i in 1:10) {
  if (i%%2==0) next # i가 짝수이면 아래 명령문 실행하지 않고, 건너 뜀! 다음 i로!
  sum <- sum + i
}
sum
## [1] 25

apply() 함수

4-15 (apply()함수의 적용)

apply(iris[,1:4], 1, mean)  # row 방향으로 함수 적용
##   [1] 2.550 2.375 2.350 2.350 2.550 2.850 2.425 2.525 2.225 2.400 2.700 2.500
##  [13] 2.325 2.125 2.800 3.000 2.750 2.575 2.875 2.675 2.675 2.675 2.350 2.650
##  [25] 2.575 2.450 2.600 2.600 2.550 2.425 2.425 2.675 2.725 2.825 2.425 2.400
##  [37] 2.625 2.500 2.225 2.550 2.525 2.100 2.275 2.675 2.800 2.375 2.675 2.350
##  [49] 2.675 2.475 4.075 3.900 4.100 3.275 3.850 3.575 3.975 2.900 3.850 3.300
##  [61] 2.875 3.650 3.300 3.775 3.350 3.900 3.650 3.400 3.600 3.275 3.925 3.550
##  [73] 3.800 3.700 3.725 3.850 3.950 4.100 3.725 3.200 3.200 3.150 3.400 3.850
##  [85] 3.600 3.875 4.000 3.575 3.500 3.325 3.425 3.775 3.400 2.900 3.450 3.525
##  [97] 3.525 3.675 2.925 3.475 4.525 3.875 4.525 4.150 4.375 4.825 3.400 4.575
## [109] 4.200 4.850 4.200 4.075 4.350 3.800 4.025 4.300 4.200 5.100 4.875 3.675
## [121] 4.525 3.825 4.800 3.925 4.450 4.550 3.900 3.950 4.225 4.400 4.550 5.025
## [133] 4.250 3.925 3.925 4.775 4.425 4.200 3.900 4.375 4.450 4.350 3.875 4.550
## [145] 4.550 4.300 3.925 4.175 4.325 3.950
apply(iris[,1:4], 2, mean)  # col 방향으로 함수 적용
## Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
##     5.843333     3.057333     3.758000     1.199333

함수(Fuctions) 만들기

4-16 (tㅏ용자 정의 함수 만들기)

mymax <- function(x,y) {
  num.max <- x
  if (y > x) {
    num.max <- y
  }
  return(num.max) 
} 

4-17 (사용자 정의 함수 사용하기)

mymax(10,15)
## [1] 15
a <- mymax(20,15)
b <- mymax(31,45)
print(a+b)
## [1] 65

4-18 (사용자 정의 함수의 매개변수에 초기값 설정하기)

mydiv <- function(x,y=2) {
  result <- x/y
  return(result) 
}

mydiv(x=10,y=3)               # 매개변수 이름과 매개변수값을 쌍으로 입력
## [1] 3.333333
mydiv(10,3)                   # 매개변수값만 입력
## [1] 3.333333
mydiv(10)                     # x에 대한 값만 입력(y 값이 생략-> 초기설정값으로 함수작동)
## [1] 5

4-19 (함수가 반환하는 결과값이 여러개 일때의 처리)

myfunc <- function(x,y) {
  val.sum <- x+y
  val.mul <- x*y 
  return(list(sum=val.sum, mul=val.mul)) 
}

result <- myfunc(5,8)
s <- result$sum         # 5, 8의 합
m <- result$mul         # 5, 8의 곱
cat('5+8=', s, '\n')
## 5+8= 13
cat('5*8=', result$mul, '\n')
## 5*8= 40

4-20 (사용자 정의 함수의 저장 및 호출)

setwd("C:/Users/SAMSUNG/rprogramming/20201-r-lecturedata/W11conditionsandloops")    # myfunc.R이 저장된 폴더
source("myfunc.R")    # myfunc.R 안에 있는 함수 실행

# 함수 사용
a <- mydiv(20,4)      # 함수 호출
b <- mydiv(30,4)      # 함수 호출
a+b
## [1] 12.5
mydiv(mydiv(20,2),5)  # 함수 호출
## [1] 2
setwd("C:/Users/SAMSUNG/rprogramming/20201-r-lecturedata") # working directory 복구

Deciding a movie to watch

my_data <- data.frame(name=c("Toy Story","Akira"),average_rating=c(8.3,8.1))

isGoodRating <- function(rating, threshold=7){
  if(rating < threshold){
    return("NO")
  }else{
    return("YES")
  }
}
watchMovie <- function(moviename, my_threshold=7){
  rating <- my_data[my_data[,1]==moviename, "average_rating"]
  isGoodRating(rating,threshold = my_threshold)
}
watchMovie("Akira")
## [1] "YES"
watchMovie("Akira",9)
## [1] "NO"

Global변수 & Local변수(지역변수)

myFunction <- function(){
  y <<- 3.14
  temp <- "Hello World"
  return(temp)
}
myFunction()
## [1] "Hello World"
y
## [1] 3.14
#temp   #에러: 객체 'temp'를 찾을 수 없습니다- temp는 지역변수이므로 return통해서만 가능!

4-21 (조건에 맞는 데이터의 위치 찾기1)

score <- c(76, 84, 69, 50, 95, 60, 82, 71, 88, 84)
which(score==69)            # 성적이 69인 학생은 몇 번째에 있나
## [1] 3
which(score>=85)            # 성적이 85 이상인 학생은 몇 번째에 있나
## [1] 5 9
max(score)                  # 최고 점수는 몇 점인가
## [1] 95
which.max(score)            # 최고 점수는 몇 번째에 있나
## [1] 5
min(score)                  # 최저 점수는 몇 점인가
## [1] 50
which.max(score)            # 최저 점수는 몇 번째에 있나
## [1] 5

4-22 (조건에 맞는 데이터의 위치 찾기2)

score <- c(76, 84, 69, 50, 95, 60, 82, 71, 88, 84)
idx <- which(score<=60)           # 성적이 60 이하인 값들의 인덱스
score[idx] <- 61                  # 성적이 60 이하인 값들은 61점으로 성적 상향 조정
score                             # 상향 조정된 성적 확인
##  [1] 76 84 69 61 95 61 82 71 88 84
idx <- which(score>=80)           # 성적이 80 이상인 값들의 인덱스
score.high <- score[idx]          # 성적이 80 이상인 값들만 추출하여 저장
score.high                        # score.high의 내용 확인
## [1] 84 95 82 88 84

4-23 (조건에 맞는 데이터의 위치 찾기3)

idx <- which(iris$Petal.Length>5.0) # 꽃잎의 길이가 5.0 이상인 값들의 인덱스
idx
##  [1]  84 101 102 103 104 105 106 108 109 110 111 112 113 115 116 117 118 119 121
## [20] 123 125 126 129 130 131 132 133 134 135 136 137 138 140 141 142 143 144 145
## [39] 146 148 149 150
iris.big <- iris[idx,]              # 인덱스에 해당하는 값만 추출하여 저장
iris.big
##     Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
## 84           6.0         2.7          5.1         1.6 versicolor
## 101          6.3         3.3          6.0         2.5  virginica
## 102          5.8         2.7          5.1         1.9  virginica
## 103          7.1         3.0          5.9         2.1  virginica
## 104          6.3         2.9          5.6         1.8  virginica
## 105          6.5         3.0          5.8         2.2  virginica
## 106          7.6         3.0          6.6         2.1  virginica
## 108          7.3         2.9          6.3         1.8  virginica
## 109          6.7         2.5          5.8         1.8  virginica
## 110          7.2         3.6          6.1         2.5  virginica
## 111          6.5         3.2          5.1         2.0  virginica
## 112          6.4         2.7          5.3         1.9  virginica
## 113          6.8         3.0          5.5         2.1  virginica
## 115          5.8         2.8          5.1         2.4  virginica
## 116          6.4         3.2          5.3         2.3  virginica
## 117          6.5         3.0          5.5         1.8  virginica
## 118          7.7         3.8          6.7         2.2  virginica
## 119          7.7         2.6          6.9         2.3  virginica
## 121          6.9         3.2          5.7         2.3  virginica
## 123          7.7         2.8          6.7         2.0  virginica
## 125          6.7         3.3          5.7         2.1  virginica
## 126          7.2         3.2          6.0         1.8  virginica
## 129          6.4         2.8          5.6         2.1  virginica
## 130          7.2         3.0          5.8         1.6  virginica
## 131          7.4         2.8          6.1         1.9  virginica
## 132          7.9         3.8          6.4         2.0  virginica
## 133          6.4         2.8          5.6         2.2  virginica
## 134          6.3         2.8          5.1         1.5  virginica
## 135          6.1         2.6          5.6         1.4  virginica
## 136          7.7         3.0          6.1         2.3  virginica
## 137          6.3         3.4          5.6         2.4  virginica
## 138          6.4         3.1          5.5         1.8  virginica
## 140          6.9         3.1          5.4         2.1  virginica
## 141          6.7         3.1          5.6         2.4  virginica
## 142          6.9         3.1          5.1         2.3  virginica
## 143          5.8         2.7          5.1         1.9  virginica
## 144          6.8         3.2          5.9         2.3  virginica
## 145          6.7         3.3          5.7         2.5  virginica
## 146          6.7         3.0          5.2         2.3  virginica
## 148          6.5         3.0          5.2         2.0  virginica
## 149          6.2         3.4          5.4         2.3  virginica
## 150          5.9         3.0          5.1         1.8  virginica

4-24 (조건에 맞는 데이터의 위치 찾기4)

# 1~4열의 값 중 5보다 큰 값의 행의 위치
idx <- which(iris[,1:4]>5.0)
idx
##   [1]   1   6  11  15  16  17  18  19  20  21  22  24  28  29  32  33  34  37
##  [19]  40  45  47  49  51  52  53  54  55  56  57  59  60  62  63  64  65  66
##  [37]  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84
##  [55]  85  86  87  88  89  90  91  92  93  95  96  97  98  99 100 101 102 103
##  [73] 104 105 106 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
##  [91] 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
## [109] 141 142 143 144 145 146 147 148 149 150 384 401 402 403 404 405 406 408
## [127] 409 410 411 412 413 415 416 417 418 419 421 423 425 426 429 430 431 432
## [145] 433 434 435 436 437 438 440 441 442 443 444 445 446 448 449 450
# 1~4열의 값 중 5보다 큰 값의 행과 열의 위치
idx <- which(iris[,1:4]>5.0, arr.ind =TRUE)
idx
##        row col
##   [1,]   1   1
##   [2,]   6   1
##   [3,]  11   1
##   [4,]  15   1
##   [5,]  16   1
##   [6,]  17   1
##   [7,]  18   1
##   [8,]  19   1
##   [9,]  20   1
##  [10,]  21   1
##  [11,]  22   1
##  [12,]  24   1
##  [13,]  28   1
##  [14,]  29   1
##  [15,]  32   1
##  [16,]  33   1
##  [17,]  34   1
##  [18,]  37   1
##  [19,]  40   1
##  [20,]  45   1
##  [21,]  47   1
##  [22,]  49   1
##  [23,]  51   1
##  [24,]  52   1
##  [25,]  53   1
##  [26,]  54   1
##  [27,]  55   1
##  [28,]  56   1
##  [29,]  57   1
##  [30,]  59   1
##  [31,]  60   1
##  [32,]  62   1
##  [33,]  63   1
##  [34,]  64   1
##  [35,]  65   1
##  [36,]  66   1
##  [37,]  67   1
##  [38,]  68   1
##  [39,]  69   1
##  [40,]  70   1
##  [41,]  71   1
##  [42,]  72   1
##  [43,]  73   1
##  [44,]  74   1
##  [45,]  75   1
##  [46,]  76   1
##  [47,]  77   1
##  [48,]  78   1
##  [49,]  79   1
##  [50,]  80   1
##  [51,]  81   1
##  [52,]  82   1
##  [53,]  83   1
##  [54,]  84   1
##  [55,]  85   1
##  [56,]  86   1
##  [57,]  87   1
##  [58,]  88   1
##  [59,]  89   1
##  [60,]  90   1
##  [61,]  91   1
##  [62,]  92   1
##  [63,]  93   1
##  [64,]  95   1
##  [65,]  96   1
##  [66,]  97   1
##  [67,]  98   1
##  [68,]  99   1
##  [69,] 100   1
##  [70,] 101   1
##  [71,] 102   1
##  [72,] 103   1
##  [73,] 104   1
##  [74,] 105   1
##  [75,] 106   1
##  [76,] 108   1
##  [77,] 109   1
##  [78,] 110   1
##  [79,] 111   1
##  [80,] 112   1
##  [81,] 113   1
##  [82,] 114   1
##  [83,] 115   1
##  [84,] 116   1
##  [85,] 117   1
##  [86,] 118   1
##  [87,] 119   1
##  [88,] 120   1
##  [89,] 121   1
##  [90,] 122   1
##  [91,] 123   1
##  [92,] 124   1
##  [93,] 125   1
##  [94,] 126   1
##  [95,] 127   1
##  [96,] 128   1
##  [97,] 129   1
##  [98,] 130   1
##  [99,] 131   1
## [100,] 132   1
## [101,] 133   1
## [102,] 134   1
## [103,] 135   1
## [104,] 136   1
## [105,] 137   1
## [106,] 138   1
## [107,] 139   1
## [108,] 140   1
## [109,] 141   1
## [110,] 142   1
## [111,] 143   1
## [112,] 144   1
## [113,] 145   1
## [114,] 146   1
## [115,] 147   1
## [116,] 148   1
## [117,] 149   1
## [118,] 150   1
## [119,]  84   3
## [120,] 101   3
## [121,] 102   3
## [122,] 103   3
## [123,] 104   3
## [124,] 105   3
## [125,] 106   3
## [126,] 108   3
## [127,] 109   3
## [128,] 110   3
## [129,] 111   3
## [130,] 112   3
## [131,] 113   3
## [132,] 115   3
## [133,] 116   3
## [134,] 117   3
## [135,] 118   3
## [136,] 119   3
## [137,] 121   3
## [138,] 123   3
## [139,] 125   3
## [140,] 126   3
## [141,] 129   3
## [142,] 130   3
## [143,] 131   3
## [144,] 132   3
## [145,] 133   3
## [146,] 134   3
## [147,] 135   3
## [148,] 136   3
## [149,] 137   3
## [150,] 138   3
## [151,] 140   3
## [152,] 141   3
## [153,] 142   3
## [154,] 143   3
## [155,] 144   3
## [156,] 145   3
## [157,] 146   3
## [158,] 148   3
## [159,] 149   3
## [160,] 150   3

Debugging(디버깅)

tryCatch()

# "a"+10        # error
10+10           # error가 나면 다음 code를 실행하지 않고 중지됨
## [1] 20
# as.integer("a")   # warning
10+10  # warning의 경우는 default warning 메시지가 나타나고 그 다음 code를 진행함 
## [1] 20
try("a"+10)  # error
## Error in "a" + 10 : 이항연산자에 수치가 아닌 인수입니다
10+10      #try문은, error가 나지만 실행을 중지하지 않고 default error 메시지 표시 후 계속 그 다음 code를 실행 
## [1] 20

error가 날 경우, tryCatch 문에서 error 처리를 하는 경우만 그 다음 code를 실행

# tryCatch("a"+10)
10+10 # tryCatch에서 error 처리를 하지 않은 관계로 default error 메시지 출력후 프로그램 실행 중지
## [1] 20
tryCatch("a"+10, error = function (e) print("error but continue next code") )
## [1] "error but continue next code"
10+10
## [1] 20
tryCatch(10+10, error = function (e) print("error but continue next code") ) # tryCatch문에 오류없을 시 그냥 명령문 수행
## [1] 20
tryCatch(10+"a", error=function(e) return("10a"))
## [1] "10a"
tryCatch(for(i in 1:3){print(i+"a")},error=function(e) print("Found error!")) #tryCatch는 오류시 안에 반복문 중단! 그리고 다음 명령문 시행!
## [1] "Found error!"
tryCatch(for(i in 1:3){print(i)},error=function(e) print("Found error!"))
## [1] 1
## [1] 2
## [1] 3