본문 바로가기
통계프로그램 비교 시리즈/프로그래밍비교(Oracle,Python,R,SAS)

[집계 함수] 데이터 유일성 체크 - 데이터 중복 제거 - 157 (오라클 SQL, R, Python, SAS)

by 기서무나구물 2023. 1. 10.

포스팅 목차

    157. Check whether all employees number are indeed unique.

     

    * 모든 직원의 사원번호가 유일하게 할당되었는지 확인하시오.


    • Oracle : count(), Distinct, Having count()
    • 파이썬 Pandas : agg()의 'count'와 'nunique'
    • R 프로그래밍 : plyr::summarise()의 length()와 length(unique()), dplyr::summarise()의 n()과 n_distinct(), broom ::tidy(), table(), Merge(), dplyr::add_tally(), dplyr::add_count(), plyr::ddply(), ave()
    • R Dplyr Package : dplyr::summarise()의 n()과 n_distinct(), is.na(), ungroup()
    • R sqldf Package : count(), Distinct
    • Python pandasql Package : count(), Distinct
    • R data.table Package : .N, uniqueN(), is.na(), dplyr::n_distinct()
    • SAS Proc SQL : count(), Distinct, Having count()
    • SAS Data Step : PROC SUMMARY의 N, Proc sort의 Nodupkey 옵션, Merge 구문, FIRST., 누적합, IF 조건문
    • Python Dfply Package : summarize()의 .count()와 .nunique()
    • 파이썬 Base 프로그래밍 :

     


    1. Oracle(오라클)

    having절에서 사원수 합계와 중복을 제거한 사원수의 합계가 같은 경우 사원수 합계와 중복을 제거한 사원수 합계를 출력한다.

     

    Oracle Programming
    select count(empno)           emp_cnt,
           count(distinct(empno)) emp_unique
    from   emp 
    having count(empno) = count(distinct(empno));

     


    2. Python Pandas(파이썬)

    agg() 함수를 사용하여서 사원수 합계와 사원번호 중복을 제거한 사원수 합계를 집계한다.

     

    Python Programming
    emp.agg({'empno':['count','nunique']})

     


    Results
      empno
    count 14
    nunique 14

     


    3. R Programming (R Package)

    plyr::summarise() 함수를 사용하여서 사원수 합계와 사원번호 중복을 제거한 사원수 합계를 집계한다.

     

    R Programming
    %%R
    
    library(plyr)
    
    plyr::summarise(emp, tot_cnt1 =length(empno), tot_cnt2 =length(unique(empno)))

     

    Results
      tot_cnt1 tot_cnt2
    1       14       14

     


    dplyr::summarise() 함수를 사용하여서 사원수 합계와 사원번호 중복을 제거한 사원수 합계를 집계한다.

     

    R Programming
    %%R
    
    dplyr::summarise(emp, tot_cnt1 = n(), tot_cnt2 = n_distinct(empno))

     

    Results
    # A tibble: 1 x 2
      tot_cnt1 tot_cnt2
         <int>    <int>
    1       14       14

     


    [참고] Group by 집계 결과를 Base Table Re-merge

    그룹(job * deptno)별로 계산된 결과의 사원수를 merge() 함수를 사용하여 대상 테이블에 그룹 변수를 기준으로 추가한다.

     

    [링크] Count number of rows per group and add result to original data frame

     

    R Programming
    %%R
    library(broom)
    print( broom ::tidy(table(emp[ , c("job","deptno")])) %>% head() )
    print("-----------------------------------------------------------------")
    df <- merge(emp, tidy(table(emp[ , c("job","deptno")])), by=c("job","deptno"))
    df %>% head(7)

     

    Results
    # A tibble: 6 x 3
      job       deptno     n
      <chr>     <chr>  <int>
    1 ANALYST   10         0
    2 CLERK     10         1
    3 MANAGER   10         1
    4 PRESIDENT 10         1
    5 SALESMAN  10         0
    6 ANALYST   20         2
    [1] "-----------------------------------------------------------------"
          job deptno empno  ename  mgr   hiredate  sal comm n
    1 ANALYST     20  7788  SCOTT 7566 1982-12-09 3000   NA 2
    2 ANALYST     20  7902   FORD 7566 1981-12-03 3000   NA 2
    3   CLERK     10  7934 MILLER 7782 1982-01-23 1300   NA 1
    4   CLERK     20  7369  SMITH 7902 1980-12-17  800   NA 2
    5   CLERK     20  7876  ADAMS 7788 1983-01-12 1100   NA 2
    6   CLERK     30  7900  JAMES 7698 1981-12-03  950   NA 1
    7 MANAGER     10  7782  CLARK 7839 1981-01-09 2450   NA 1

     


    group_by()에 지정한 그룹(job * deptno) 변수별로 계산된 사원수를 add_tally()함수를 사용하여 테이블 조인 없이 자동으로 대상 테이블에 그룹 변수를 기준으로 추가한다.

     

    dplyr::add_count()는 별도의 group_by() 함수를 사용하지 않고, 내부에 group by 변수를 함께 지정하여 계산된 결과를 자동으로 대상 테이블에 그룹 변수를 기준으로 추가된다.

     

    R Programming
    %%R
    
    print ( emp  %>% group_by(deptno, job) %>% dplyr::add_tally() %>% head(7) )
    
    dplyr::add_count(emp, job, deptno) %>% head(7)

     

    Results
    # A tibble: 7 x 9
    # Groups:   deptno, job [5]
      empno ename  job        mgr hiredate     sal  comm deptno     n
      <dbl> <chr>  <chr>    <dbl> <date>     <dbl> <dbl>  <dbl> <int>
    1  7369 SMITH  CLERK     7902 1980-12-17   800    NA     20     2
    2  7499 ALLEN  SALESMAN  7698 1981-02-20  1600   300     30     4
    3  7521 WARD   SALESMAN  7698 1981-02-22  1250   500     30     4
    4  7566 JONES  MANAGER   7839 1981-04-02  2975    NA     20     1
    5  7654 MARTIN SALESMAN  7698 1981-09-28  1250  1400     30     4
    6  7698 BLAKE  MANAGER   7839 1981-03-01  2850    NA     30     1
    7  7782 CLARK  MANAGER   7839 1981-01-09  2450    NA     10     1
    # A tibble: 7 x 9
      empno ename  job        mgr hiredate     sal  comm deptno     n
      <dbl> <chr>  <chr>    <dbl> <date>     <dbl> <dbl>  <dbl> <int>
    1  7369 SMITH  CLERK     7902 1980-12-17   800    NA     20     2
    2  7499 ALLEN  SALESMAN  7698 1981-02-20  1600   300     30     4
    3  7521 WARD   SALESMAN  7698 1981-02-22  1250   500     30     4
    4  7566 JONES  MANAGER   7839 1981-04-02  2975    NA     20     1
    5  7654 MARTIN SALESMAN  7698 1981-09-28  1250  1400     30     4
    6  7698 BLAKE  MANAGER   7839 1981-03-01  2850    NA     30     1
    7  7782 CLARK  MANAGER   7839 1981-01-09  2450    NA     10     1

     


    plyr::ddply() 함수에 transform 인수를 지정하여서 group by 변수를 함께 지정하여 계산된 결과를 자동으로 대상 테이블에 그룹 변수를 기준으로 추가된다.

     

    R Programming
    %%R
    
    plyr::ddply(emp, .(job, deptno), transform, emp_cnt = length(empno)) %>% head(5)

     

    Results
      empno  ename     job  mgr   hiredate  sal comm deptno emp_cnt
    1  7788  SCOTT ANALYST 7566 1982-12-09 3000   NA     20       2
    2  7902   FORD ANALYST 7566 1981-12-03 3000   NA     20       2
    3  7934 MILLER   CLERK 7782 1982-01-23 1300   NA     10       1
    4  7369  SMITH   CLERK 7902 1980-12-17  800   NA     20       2
    5  7876  ADAMS   CLERK 7788 1983-01-12 1100   NA     20       2

     


    그룹별로 계산된 관측치 건수(사원수 합계)를 withmooc 테이터프레임에 추가한다.

     

    R Programming
    %%R
    withmooc <- emp
    withmooc$emp_cnt <- ave(withmooc$empno, withmooc[,c("job","deptno")], FUN=length)
    
    withmooc[1:7, ]

     

    Results
    # A tibble: 7 x 9
      empno ename  job        mgr hiredate     sal  comm deptno emp_cnt
      <dbl> <chr>  <chr>    <dbl> <date>     <dbl> <dbl>  <dbl>   <dbl>
    1  7369 SMITH  CLERK     7902 1980-12-17   800    NA     20       2
    2  7499 ALLEN  SALESMAN  7698 1981-02-20  1600   300     30       4
    3  7521 WARD   SALESMAN  7698 1981-02-22  1250   500     30       4
    4  7566 JONES  MANAGER   7839 1981-04-02  2975    NA     20       1
    5  7654 MARTIN SALESMAN  7698 1981-09-28  1250  1400     30       4
    6  7698 BLAKE  MANAGER   7839 1981-03-01  2850    NA     30       1
    7  7782 CLARK  MANAGER   7839 1981-01-09  2450    NA     10       1

     


    mutate() 함수를 사용하여서 그룹별로 계산된 관측치 건수(사원수 합계)를 withmooc 테이터프레임에 추가한다.

     

    R Programming
    %%R
    
    emp %>%
      group_by(job,deptno) %>%
      mutate( tot_cnt1 = length(empno), tot_cnt2 = n_distinct(empno)) %>%
      head()

     

    Results
    # A tibble: 6 x 10
    # Groups:   job, deptno [4]
      empno ename  job        mgr hiredate     sal  comm deptno tot_cnt1 tot_cnt2
      <dbl> <chr>  <chr>    <dbl> <date>     <dbl> <dbl>  <dbl>    <int>    <int>
    1  7369 SMITH  CLERK     7902 1980-12-17   800    NA     20       14       14
    2  7499 ALLEN  SALESMAN  7698 1981-02-20  1600   300     30       14       14
    3  7521 WARD   SALESMAN  7698 1981-02-22  1250   500     30       14       14
    4  7566 JONES  MANAGER   7839 1981-04-02  2975    NA     20       14       14
    5  7654 MARTIN SALESMAN  7698 1981-09-28  1250  1400     30       14       14
    6  7698 BLAKE  MANAGER   7839 1981-03-01  2850    NA     30       14       14

     


    4. R Dplyr Package

    dplyr::summarise() 함수를 사용하여서 사원수 합계와 사원번호 중복을 제거한 사원수 합계를 집계한다.

     

    R Programming
    %%R
    emp %>% 
      dplyr::summarise( tot_cnt1 = n(), tot_cnt2 = n_distinct(empno))

     

    Results
    # A tibble: 1 x 2
      tot_cnt1 tot_cnt2
         <int>    <int>
    1       14       14

     


    summarise() 함수를 사용하여서 na값을 제외한 사원수와 사원번호 중복을 제거한 사원수 합계를 집계한다.

     

    R Programming
    %%R
    
    emp %>%
      summarise(tot_cnt1 = sum(!is.na(empno)), tot_cnt2 = dplyr::n_distinct((empno), na.rm = TRUE)) %>%
      ungroup()

     

    Results
      tot_cnt1 tot_cnt2
    1       14       14

     


    5. R sqldf Package

    사원수 전체 합계와 중복을 제거한 사원수의 합계를 출력한다.

     

    R Programming
    %%R
    
    sqldf(" select count(empno)           tot_cnt1, 
                   count(distinct(empno)) tot_cnt2 
            from   emp")

     

    Results
      tot_cnt1 tot_cnt2
    1       14       14

     


    6. Python pandasql Package

     

    Python Programming
    ps.sqldf(" select count(empno) tot_cnt1, count(distinct(empno)) tot_cnt2 \
               from   emp ")

     

    Results
      tot_cnt1 tot_cnt2
    0 14 14

     


    7. R data.table Package

    사원수 합계(.N)와 사원번호 중복을 제거한 사원수 합계(uniqueN)를 집계한다.

     

    R Programming
    %%R
    
    DT <- data.table(emp)
    
    DT[,.(tot_cnt1 = .N, tot_cnt2 = uniqueN(empno))]

     

    Results
       tot_cnt1 tot_cnt2
    1:       14       14

     


    na값을 제외한 사원수와 사원번호 중복을 제거한 사원수 합계를 집계한다.

     

    R Programming
    %%R
    
    DT[, .(tot_cnt1 = sum(!is.na(empno)), tot_cnt2 = dplyr::n_distinct((empno), na.rm = TRUE))]

     

    Results
       tot_cnt1 tot_cnt2
    1:       14       14

     


    8. SAS Proc SQL

    having절에서 사원수 합계와 중복을 제거한 사원수의 합계가 같은 경우 사원수 합계와 중복을 제거한 사원수 합계를 출력한다.

     

    SAS Programming
    %%SAS sas
    
    PROC SQL;
      CREATE TABLE STATSAS_1 AS
        select count(empno) AS emp_cnt,
               count(distinct(empno)) AS emp_unique
        from   emp 
        having count(empno) = count(distinct(empno));
    QUIT;
    PROC PRINT;RUN;

     

    Results
    OBS emp_cnt emp_unique
    1 14 14

     


    9. SAS Data Step

     

    SAS Programming
    %%SAS sas
    
    PROC SUMMARY DATA=EMP NWAY;
         VAR   EMPNO;
         OUTPUT OUT=STATSAS_2(DROP=_:) N=emp_cnt;
    QUIT;
    
    PROC SORT DATA=EMP OUT=EMP_1 NODUPKEY;
         BY EMPNO;
    RUN;
    PROC SUMMARY DATA=EMP_1 NWAY;
         VAR   EMPNO;
         OUTPUT OUT=STATSAS_3(DROP=_:) N=emp_unique;
    QUIT;
    
    DATA STATSAS_4;
     MERGE STATSAS_2 STATSAS_3;
    RUN;
    
    PROC PRINT;RUN;

     


    Results
    OBS emp_cnt emp_unique
    1 14 14

     


    SAS Programming
    %%SAS sas
    
    PROC SORT DATA=EMP OUT=EMP_2;
         BY EMPNO;
    RUN;
    
    DATA STATSAS_5;
     SET EMP_2 nobs=obs_cnt;
         BY EMPNO;
         EMP_CNT + 1;
    
         IF FIRST.EMPNO THEN emp_unique + 1;
         if _n_ = obs_cnt then output;
         keep emp_cnt emp_unique;
    RUN;
    PROC PRINT;RUN;

     

    Results
    OBS EMP_CNT emp_unique
    1 14 14

     


    SAS Programming
    %%SAS sas
    
    PROC SORT DATA=EMP OUT=EMP_2;
         BY JOB;
    RUN;
    
    DATA STATSAS_5;
     SET EMP_2 NOBS=OBS_CNT;
         BY JOB;
         EMP_CNT + 1;
    
         IF FIRST.JOB THEN job_unique + 1;
         IF _N_ = OBS_CNT;
         KEEP EMPNO ENAME EMP_CNT job_unique;
    RUN;
    PROC PRINT;RUN;

     

     

    Results
    OBS empno ename EMP_CNT job_unique
    1 7844 TURNER 14 5

     


    10. Python Dfply Package

     

    Python Programming
    emp >> summarize( emp_cnt = X.empno.count() ,emp_unique  = X.empno.nunique() )

     

     

    Results
      emp_cnt emp_unique
    0 14 14

     


     

    [SQL, Pandas, R Prog, Dplyr, SQLDF, PANDASQL, DATA.TABLE]   SQL EMP 예제로 만나는 테이블 데이터 전처리 방법 리스트

    반응형

    댓글