논리연산자 AND, OR R , if 문 과 for 문 사용법과 dplyr 사용법 비교

  논리연산자 AND,OR는  실무에서 많이 쓰이는 방법이다.  R을 처음 시작 하는 컴퓨터 프로그래머는 for문을 많이 사용한다.  하지만 R에서 for문은 속도 측면에서 최악이다.   그리고 AND, OR, IF 문도 for문을 돌리지 않고 dplyr에서 간단하게 사용할 수 있다. 


기호의미
!논리연산자 NOT
&논리연산자 AND
|논리연산자 OR
<미만
<=이하
>초과
>=이상
==논리연산자 일치
!=논리연산자 불일치
||조건문에서  OR
&&조건문에서  AND
xor(x,y)베타논리합
isTRUE(x)identical(TRUE. X)의 축약

3-2 논리연산자

논리연산의 핵심읜 사실에 대한 질문이다. 예를 들어 “이 값이 다른 값보다 큰가? 2개 모두 같은 크기인가?라는 질문에 대해 복수 연산을 하기 위해서는 and,dor,nor와 같은 연산자를 결합하여 표현할 수 있습니다. R언어에서 질문은 참(TRUE)이나 거짓(FALSE)으로 연산하지만 아마도와 같이 답변이 없는 경우(NA)도 있다. R에서 부동호 (<)는 보다 작은을 의미하고, 부등호(>)는 보다 큰을 의미하는 느낌표(!)는 부정을 의미합니다.. (위의 표 참고)

3.2.1 TRUE와 T.FALSE와 F

참에는 T를 사용하고 거짓에는 F를 사용할 수 있지 만. T와 F가 변수가 될 수 있음을 알고 있어야 합니다. 아래의 예제를 참고 하십시오.

TRUE==FALSE
## [1] FALSE
T==F
## [1] FALSE

그러나 다음과 같이 T 와 F가 변수명으로 사용되는 경우 반드시 T가 TRUE이고, F가 FALSE를 의미한다고 판단 할 수 없습니다.

T<-0
T==FALSE
## [1] TRUE

예제의 변수T는 F와 다릅니다.

T!=F
## [1] FALSE

확실히 해두기 위해서는 항상 TRUE와 FALSE를 모두 기입하고 변수명으로 T 또는 F를 절대로 사용하지 않습니다.

3.2.2 실수값에 대한 동등 여부 테스트

부동 소수점 연산을 위한 국제 표준이 있지만, 컴퓨터 상에서 이러한 표준은 R의 통제 범위를 벗어 납니다. 대략, 정수 연산을 1016에서 1016까지이지만 분수나 실수에 대해서는 반올림 오류로 힌해 정확도를 잃게 됩니다. 아래의 예제를 보면 알수 있습니다.

  x<-sqrt(2) 
  x*x==2
## [1] FALSE
  x 
## [1] 1.414214
  x*x
## [1] 2

사실 두 값(2의 제곱근의 자승, 실제값 2)은 같지 않습니다. 두값의 차이를 뺄셈을 통하여 알아 볼수 있습니다.

  x*x-2
## [1] 4.440892e-16

3.2.3 all.equal을 사용한 부동 소수점 숫자의 동등 여부 확인

컴퓨터 연산에서 사용한 부동 소수점 자릿수의 특성은 일부 기대하지 않은 문제를 발생시킴니다. 예를 들어 0.3에서 0.2를 배면 0.1이므로 다음 논리연산은 TRUE가 되어야 하지만 실제로는 그렇지 않습니다.

x<-0.3-0.2
y<-0.1
x == y
## [1] FALSE

identical 함수도 같은 오류가 발생 합니다.

identical(x,y)
## [1] FALSE

따라서 이에 대한 해결 방법은 미미한 차이를 허용하는 all.equal 함수를 사용합니다.

all.equal(x,y)
## [1] TRUE

if문에서는 직접적으로 all.equl 을 사용하지 않습니다. 대신 isTRUE(all.equal(….)) 또는 identical 함수를 사용합니다.

예제 1

아래는 빅데이터처리기사 시험 결과 입니다. 시험 기준은 평균점수 60점 이상이고, 40점 이하는 과락 이라는 기준이 있습니다. 아래 시험에서 합격자와 불합격자를 조건 연산자를 이용하여 결과를 정리 하십시오.

수험생번호분석기획데이터탐색모델링결과해석
A000160454055
A000235604048
A000370707065
A000455554039
A000560707070
A000680604040
A000780506050
A000860355045
A000980657030
A001060605550



1. 평균점수 이하 케이스

  수험생번호 <- c("A0001","A0002","A0003","A0004","A0005","A0006","A0007",
                  "A0008","A0009","A0010")
  분석기획 <-c(60,35,70,55,60,80,80,60,80,60)
  데이터탐색<-c(45,60,70,55,70,60,50,35,65,60)
  모델링<-c(40,40,70,40,70,40,60,50,70,55)
  결과해석<-c(55,48,65,39,70,40,50,45,30,50)
  
  
  df <- data.frame(수험생번호, 분석기획, 데이터탐색, 모델링, 결과해석)
  df
##    수험생번호 분석기획 데이터탐색 모델링 결과해석
## 1       A0001       60         45     40       55
## 2       A0002       35         60     40       48
## 3       A0003       70         70     70       65
## 4       A0004       55         55     40       39
## 5       A0005       60         70     70       70
## 6       A0006       80         60     40       40
## 7       A0007       80         50     60       50
## 8       A0008       60         35     50       45
## 9       A0009       80         65     70       30
## 10      A0010       60         60     55       50


고전적으로 체크 하는 방법 입니다. 조금 길지만 예전에 C, Python, Java언어를 사용 한 경험이 있다면 쉽게 이해 할 수 있는 부분 입니다.

# 첫번째 행 수험생 번호를 제외 하고, 나타냄 
  x <- df[2:4]
  x
##    분석기획 데이터탐색 모델링
## 1        60         45     40
## 2        35         60     40
## 3        70         70     70
## 4        55         55     40
## 5        60         70     70
## 6        80         60     40
## 7        80         50     60
## 8        60         35     50
## 9        80         65     70
## 10       60         60     55
# apply 함수 1 열 계산으로 평균을 구함  
  avg_score <- apply(x, 1, mean)
  avg_score   
##  [1] 48.33333 45.00000 70.00000 50.00000 66.66667 60.00000 63.33333 48.33333
##  [9] 71.66667 58.33333
# 소숫점 정리  round 함수  
  avg_score <-round(avg_score)
  avg_score
##  [1] 48 45 70 50 67 60 63 48 72 58
# 빈 vector 만들기 
  check <-c() 
  
# 합격 여부 확인 for  문 
  for(i in 1:length(avg_score)){
    if(avg_score[i] >= 60){
      check<-c(check, "YES")
    } else {
      check<-c(check,"NO")
    }
  }

# 데이터 합치기 
 df1 <- data.frame(df, 평균점수 = avg_score , 평균점수충족 = check )
 df1
##    수험생번호 분석기획 데이터탐색 모델링 결과해석 평균점수 평균점수충족
## 1       A0001       60         45     40       55       48           NO
## 2       A0002       35         60     40       48       45           NO
## 3       A0003       70         70     70       65       70          YES
## 4       A0004       55         55     40       39       50           NO
## 5       A0005       60         70     70       70       67          YES
## 6       A0006       80         60     40       40       60          YES
## 7       A0007       80         50     60       50       63          YES
## 8       A0008       60         35     50       45       48           NO
## 9       A0009       80         65     70       30       72          YES
## 10      A0010       60         60     55       50       58           NO


apply(객체, 행렬선택, 함수)를 이용하면, 열 계산을 할수 있습니다.. 하지만, 수험생번호는 숫자열이 아니기 때문에, 이부분을 빼고 행을 선택 하였습니다.. x <- df[2:4]

apply함수에서 (x, 1, mean)을 사용하면, 객체 x 의 열, 평균함수로 연산할 수 있습니다. 그리고 round 함수를 이용해서, 반올림 처리 하였습니다. 빈 vector를 만들어, for 문을 돌려, 평균점수와 합격 여부를 조건문 >=을 이용해서 판정(“YES”,“NO”)하였습니다.

dplyr 패키지를 이용하는 방법

dpylyr을 사용하게 되면, 위에서 사용하였던 방법이 단 4줄로 끝나게 된다. R Base 함수에서 apply 함수로 열을 구할 수 있지만, rowMeans()를 이용 해서 행의 평균을 계산 할 수 있습니다. 그런 다음에 ifelse() 함수를 사용를 사용하여,

# dplyr 라이브러리 불러오기 
 library(dplyr)
## 
## 다음의 패키지를 부착합니다: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
# dplyr을 이용하는 방법
 df2 <- df %>% 
         mutate(평균점수 = rowMeans(df[2:4]),
                평균점수 = round(평균점수,0)) %>% 
         mutate(평균점수충족 = ifelse(평균점수 >=60, "YES", "NO")) 
 
# data.frame 둘이 같은지 확인 
  all.equal(df1,df2)
## [1] TRUE



2. 과락 케이스

  • 일반적인 방법 for 문을 이용하는 방법이다. 데이터 프레임에서 과락여부 빈 필드를 만든 다음, 과목별로 변수를 만들어, 그 중에서 40점 이하인것(OR 조건)을 찾아서 과락된 과목을 찾습니다.
# 미리 데이터 셋 만들기 
 df1$과락여부 <- ""
  
# for을 사용 하는 방법 과락여부 판단  OR 문으로 판단하여야 함
  for(i in 1:nrow(df1)){
    a <- df1$분석기획[i] # 분석기획
    b <- df1$데이터탐색[i] # 데이터 탐색
    c <- df1$모델링[i] # 모델링
    d <- df1$결과해석[i] # 결과해석
  
    if(a<40 | b<40 | c<40 | d<40) {
       df1$과락여부[i] <- "YES"  
    } else {
      df1$과락여부[i] <- "NO"
    } 
  }  
  df1 %>% 
    select(수험생번호, 평균점수, 평균점수충족, 과락여부)
##    수험생번호 평균점수 평균점수충족 과락여부
## 1       A0001       48           NO       NO
## 2       A0002       45           NO      YES
## 3       A0003       70          YES       NO
## 4       A0004       50           NO      YES
## 5       A0005       67          YES       NO
## 6       A0006       60          YES       NO
## 7       A0007       63          YES       NO
## 8       A0008       48           NO      YES
## 9       A0009       72          YES      YES
## 10      A0010       58           NO       NO

최종합격은 평균점수충족여부(YES)와 과락여부(NO)를 두가지 조건을 충족 하는 AND 조건이 맞아야 합니다. 따라서 아래와 같이 for 문을 돌리면, 최종합격 여부를 산출 할수 있습니다.

# 합격여부 필드 초기화  
 df1$합격여부 <- ""
  
# 최종합격  for 문을 활용  평균이상이  YES, 이고 
# 과락여부가 NO인 경우 합격임    
  for(i in 1:nrow(df1)){
    a <- df1$평균점수충족[i]
    b <- df1$과락여부[i]

    
    if(a == "YES" && b == "NO"){
      df1$합격여부[i] <- "합격"
    } else {
      df1$합격여부[i] <- "불합격"
    }
  }
  df1 %>% 
    select(수험생번호, 평균점수, 평균점수충족, 과락여부, 합격여부)    
##    수험생번호 평균점수 평균점수충족 과락여부 합격여부
## 1       A0001       48           NO       NO   불합격
## 2       A0002       45           NO      YES   불합격
## 3       A0003       70          YES       NO     합격
## 4       A0004       50           NO      YES   불합격
## 5       A0005       67          YES       NO     합격
## 6       A0006       60          YES       NO     합격
## 7       A0007       63          YES       NO     합격
## 8       A0008       48           NO      YES   불합격
## 9       A0009       72          YES      YES   불합격
## 10      A0010       58           NO       NO   불합격



dplyr을 활용한 합격여부 확인
dplyr을 이용하면 엑셀에서 사용하는 것처럼 ifelse 함수로 모든 조건문을 제어 할수 있습니다. 즉 R에서는 굳이 for문을 돌리지 않고도, 모든 연산을 할수 있습니다. for 문을 사용하는 것은 Big Data연산에서 속도 느림 현상이 발생 할 수 있습니다.

  df2 %>% 
    mutate(과락여부 =  ifelse(분석기획<40 | 데이터탐색<40 |
                              모델링<40 | 결과해석<40,
                              "YES", "NO")) %>% 
    mutate(합격여부 = ifelse(평균점수충족 == "YES" & 과락여부 =="NO",
                             "YES","NO")) %>% 
    select(수험생번호, 평균점수, 평균점수충족, 과락여부, 합격여부) 
##    수험생번호 평균점수 평균점수충족 과락여부 합격여부
## 1       A0001       48           NO       NO       NO
## 2       A0002       45           NO      YES       NO
## 3       A0003       70          YES       NO      YES
## 4       A0004       50           NO      YES       NO
## 5       A0005       67          YES       NO      YES
## 6       A0006       60          YES       NO      YES
## 7       A0007       63          YES       NO      YES
## 8       A0008       48           NO      YES       NO
## 9       A0009       72          YES      YES       NO
## 10      A0010       58           NO       NO       NO

지금까지 논리연산자 소개와 예제를 통해서 이를 활용하는 방법을 알아 보았습니다. 위의 사례를 이해하면, 실무 업무를 어느정도 이해를 할 수 있습니다.

댓글 없음:

댓글 쓰기

css cheat sheet 클래스 선택자, margin(마진), display , center 조정 간단한 구성 요소

 앞에서는 html의 간단한 sheet를 소개 하였습니다.   html은  주로 골격을 나타나는 것이라, 디자인을 하는데는 css로 하여야 합니다.  아래 코드와 같이 css 관련 하여 매우 간단하게 코딩 하겠습니다.  body 부분의 css 코딩  ...