본문 바로가기
R 과 데이터분석/기초 문법 ~ 머신러닝

[R 데이터분석] 4장. 제어문과 함수

by JoyfulS 2019. 9. 13.

# chap04_Control

 

# 제어문과 함수

# <실습> 산술연산자, 관계연산자, 논리연산자

# 1. 조건문     ( if, ifelse, switch )

# 2. 반복문     ( for, while )

 

############################### 
## 제어문 : 조건문 + 반복문  
###############################

 

# <실습> 산술연산자 
num1 <- 100 # 피연산자1
num2 <- 20  # 피연산자2
result <- num1 + num2 # 덧셈
result # 120
result <- num1 - num2 # 뺄셈
result # 80
result <- num1 * num2 # 곱셈
result # 2000
result <- num1 / num2 # 나눗셈
result # 5

result <- num1 %% num2 # 나머지 계산
result # 0

result <- num1^2 # 제곱 계산(num1 ** 2)
result # 10000
result <- num1^num2 # 100의 20승
result # 1e+40 -> 1 * 10의 40승과 동일한 결과


# <실습> 관계연산자 
# (1) 동등비교 
boolean <- num1 == num2 # 두 변수의 값이 같은지 비교
boolean # FALSE
boolean <- num1 != num2 # 두 변수의 값이 다른지 비교
boolean # TRUE

# (2) 크기비교 
boolean <- num1 > num2 # num1값이 큰지 비교
boolean # TRUE
boolean <- num1 >= num2 # num1값이 크거나 같은지 비교 
boolean # TRUE
boolean <- num1 < num2 # num2 이 큰지 비교
boolean # FALSE
boolean <- num1 <= num2 # num2 이 크거나 같은지 비교
boolean # FALSE

# <실습> 논리연산자(and, or, not, xor)
logical <- num1 >= 50 & num2 <=10 # 두 관계식이 같은지 판단 
logical # FALSE
logical <- num1 >= 50 | num2 <=10 # 두 관계식 중 하나라도 같은지 판단
logical # TRUE

logical <- num1 >= 50 # 관계식 판단
logical # TRUE
logical <- !(num1 >= 50) # 괄호 안의 관계식 판단 결과에 대한 부정
logical # FALSE

x <- TRUE; y <- FALSE
xor(x,y) # [1] TRUE
x <- TRUE; y <- TRUE
xor(x,y) # FALSE



#########################
### 1. 조건문
#########################

# (1) if() 함수 

# if(조건식){ # 조건식 : 산술,관계,논리
#    실행문 -> 참(TRUE)
# }else{
#    실행문 -> 거짓(FALSE)
# }

score <- 55
if(score >= 60){
  print("합격") # TRUE
}else{
  print("불합격") # FALSE
}

# 키보드 점수 입력받기 
score <- scan()
score # 85

# 등급(grade) : A,B,C,D,F학점 

grade <- "" 
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"
}

cat("당신의 점수는 ", score, "점이고, 당신의 학점은 ", 
    grade, "학점")

10 / 2 # 5
10 %% 2 # 0

# 문1) 키보드로 임의의 숫자를 입력받아서 짝수/홀수 구분하기 
input <- scan()
input # 55

if(input %% 2 == 0){
   print("짝수")
}else{
   print("홀수")
}

# "홀수"

# 문2) 주민번호 14자리를 입력받아서 남자/여자 구분하기 
jumin <- "123456-5234567"

library(stringr)
gender <- str_sub(jumin, 8,8)
gender # "1"

if(gender == "1" | gender == "3"){
   print("남자")
}else if(gender == "2" | gender == "4"){
   print("여자")
}else{
  print("주민번호 형식 틀림")
}


# 2) ifelse(조건식, 참(T), 거짓(F))
# 입력 vector -> 출력 vector 

score <- c(80,65,55,75,50)
score

ifelse(score >= 60, "합격", "불합격")

 

### 사용된 파일은 https://joyfuls.tistory.com/4 에서 다운 받으실 수 있습니다.


setwd("c:/2_Rwork/Part-I")
excel <- read.csv("excel.csv")
excel
str(excel)
# data.frame': 402 obs. of  5 variables

q5 <- excel$q5
length(q5)
q5
range(q5) # 1 ~ 5

# [실습] 범주형 변수 
q6 <- ifelse(q5 >= 3, "큰 값", "작은 값")
excel$q6 <- q6
excel

table(excel$q6)
# 작은 값   큰 값 
#      89     313
89  +   313 # 402

# [실습] 결측치(NA) -> 평균 대체 
kor <- c(74,85,NA,75,NA)
kor # 74 85 NA 75 NA
mean(kor, na.rm = T) # 78

is.na(kor) 
# FALSE FALSE  TRUE FALSE  TRUE

ifelse(is.na(kor), mean(kor, na.rm = T), kor)
# 74 85 78 75 78


# 3) switch() : 다중선택문 
# 형식) switch(비교구문, 실행구문1, ... n)

switch("pwd", name="홍길동", id="hong", pwd="1234")
# hong

# 4) which() : 조건에 만족하는 index 반환 
x <- c(2,3,5,6,8)
x

which(x == 6) # 4
x[4] # 6

html <- read.csv("html_cont.csv")
html

which(html$State == "Hawaii") # 13

html[13, ]


#########################
### 2. 반복문
#########################

# 1) for()
# 형식)  for(변수 in 벡터변수){ 반복문 }

i <- 2:8
i # 2 3 4 5 6 7 8
length(i) # 7

for(x in i){ # 7회 반복
  cat("x ->", x, "\n") # 문자열 + 변수, 줄바꿈 없음  
  print(x*2) # 줄바꿈 제공 
}

# for + if
for(x in i){ # 7회 반복 
   if(x %% 2 != 0){ # 홀수 출력 
     cat("x ->", x, "\n")
   }
}

# 문) 1~100까지 홀수/짝수 합 계산하기 
even <- 0 # 짝수합 
odd <- 0 # 홀수합 

i <- 1:100
i
for(x in i){
  if(x %% 2 == 0){
     even <- even + x 
  }else{
     odd <- odd + x
  }
}

cat("짝수의 합 =", even, "홀수의 합 =", odd)
# 짝수의 합 = 2550 홀수의 합 = 2500

# 성적처리 
kor <- c(81, 95, 70)
eng <- c(75, 88, 78)
mat <- c(78, 99, 66)
name <- c("홍길동","이순신","유관순")

student <- data.frame(name, kor,eng, mat)
student

# 총점, 평균 칼럼 추가 
tot <- student$kor + student$eng + student$mat
tot # 234 282 214
avg <- round(tot / 3, 2)
avg # 78.00 94.00 71.33

student$avg <- avg
student$tot <- tot
student

# grade 칼럼 추가 
#    name kor eng mat   avg tot grade
#1 홍길동  81  75  78 78.00 234    C
#2 이순신  95  88  99 94.00 282    A
#3 유관순  70  78  66 71.33 214    C

grade <- "" # 등급 변수 
size <- length(name) # 전체 학생수 
for(i in 1:size){ # 1 2 3
  if(student$avg[i] >= 90){
    grade[i] <- "A"
  }else if(student$avg[i] >= 80){
    grade[i] <- "B"
  }else if(student$avg[i] >= 70){
    grade[i] <- "C"
  }else{
    grade[i] <- "F"
  } 
}

# 등급 칼럼 추가 
student$grade <- grade
student

kospi <- read.csv(file.choose()) # sam_kospi.csv
# 변수 구조보기 
str(kospi)
# 'data.frame'(자료구조): 247 obs.(관측치) of  6 variables(변수):
head(kospi)

# 파생변수 : 기존변수 이용 
kospi$diff <- kospi$High - kospi$Low
head(kospi)


mean(kospi$diff) # 27028.34

# 파생변수 : diff변수 
diff_result = "" 

row <- nrow(kospi)
row # 247
rows <- 1:row
for(idx in rows){ # 247반복 
  if(kospi$diff[idx] >= mean(kospi$diff)){
    diff_result[idx] <- "평균 이상"
  }else{
    diff_result[idx] <- "평균 미만"
  }
}

kospi$diff_result <- diff_result
head(kospi)

# 이중for : 구구단(2~9)
for(i in 2:9){ # 단수
  cat("***",i,"단***\n")
  for(j in 1:9){ # 곱수
    cat(i,'*',j,'=',(i*j),'\n')
  } # inner for
  cat("\n") # 빈줄 
} # outer for


# 2) while(조건식)

i <- 0 # 초기화 
while(i < 10){ # i >= 10 : 블럭 exit
  #조건식이 참이면 블럭 수행 
  cat('i=', i,'\n')
  i <- i + 1 # 카운터 
}


x <- 1:100
x

# 문) x의 원소중 5의 배수만 출력하기 : while() 이용 
i <- 0
while (i < 100) {
  i <- i + 1 # index 역할 
  if(x[i] %% 5 == 0){
    cat(x[i], " ")
  }
}

# for() 이용 
for(i in x){
  if(i %% 5 == 0){
    cat(i, " ")
  }
}


댓글