본문 바로가기
  • "You can't manage what you can't measure" Peter Drucker
데이터 분석 (with Rstudio)

R_엑셀_SQL 비교

by Vitaminymc 2023. 8. 30.
반응형

R_엑셀 (Excel)_SQL 비교

적은 데이터의 빠른 분석은 엑셀이 우수하나,

대용량 데이터 및 반복적인 데이터 가공, 그래프 생성 등 데이터 분석을 통한 Insight 도출에는 R이 적합하며,

실무에는 R과 엑셀을 함께 사용함

(엑셀의 장단점과 R)

  R Excel SQL 비고
접근성
(학습, 활용 등)
비교적 어려움
(데이터 분석
목적)
쉬움 어려움
(데이터 I/O
목적)
- Rstudio와 유사하게 별도 SQL 프로그램 필요 
  (유료, 무료)
- SQL 사용 환경 설정 필요 (DB 연결 등)
- Google Big Query 활용한 SQL 작업 가능
- Google Colab은 Python을 활용할 수 있도록
  환경을 제공하나, R코드도 사용 가능 
함수사용 어려움 쉬움 어려움 - 함수 사용은 어려우나, 확장성 보유
  (관련 패캐지 추가)
- 코드 형태로 복사하여 재사용 용이
   (필요시, 일부 수정)
분석 가능한
데이터량
무한대
(하드웨어에
따라 다름)
최대
1,048,576행
무한대
(하드웨어에
따라 다름)
- Row보다 Column이 더 중요
- Column이 증가하면, Excel은 처리 속도 저하로
  분석 어려움
분석/조작
성능
우수 낮음 우수 - Excel은 데이터량, 파일 사이즈, 함수사용 등이 
  성능에 영향이 큼
- 단순한 데이터 추출 및 1차적원인 분석에는 
  SQL이 적합
- R은 연속적인 데이터 변환 용이
반복 작업 우수 낮음 우수 - Excel은 Macro로 가능하나, 제한적
데이터 확인 불편 우수 불편 - Excel은 데이터 수정이나 함수 사용내역을
  바로 확인 용이
- 단, 데이터 또는 수식 오류의 추적성 측면에서
  R과 SQL이 우수 
  (코드를 통한 데이터 가공 이력 조회)
데이터 시각화 우수 우수 불가 - Excel은 그래프(Chart) 작성 편의성 우수
- R은 Chart 결합 등 여러 형태로 시각화 가능

상기 비교표는 아래 참고자료를 기반으로 편집 및 내용 추가함

참고 자료 : https://jayceepark.github.io/posts/2020-07-24/R_VS_EXCEL_VS_SQL

 

접근성과 함수 사용의 어려움은 언어 사용의 숙련도 향상과 다른 스크립트 활용을 통해서 해결 가능

 

언어 사용의 숙련도 향상 방법

1. 책, 블로그 예제 따라 하기

2. 실무 엑셀 분석(피벗 등) R로 변환하여 실행해 보기

3. 관심 데이터 (Kaggle 등 검색) 활용하여 연습하기

 

다른 스크립트 활용

1. 기존 작성 스크립트 복사하여 재활용 (데이터 변경, 변수명 변경)

2. 인터넷 검색을 통해, 다른 사람이 작성한 유사 스크립트 복사 및 수정 활용

3. chat GPT (Generative pre-trained transformer)에 코드 작성 요청

 

삼성SDS, LG CNS 같은 SI (System Integration) 회사는 내부 절차에 따라

고급 DB 및 SQL 프로그램(유료)을 설치하여 사용할 수 있지만,

일반 회사는 무료 SQL 프로그램이더라도 Software 관리 정책에 따라 설치가 불가능한 경우가 있음

R은 누구나 무료로 사용할 수 있는 프로그램이라는 장점이 있음

 

R과 SQL + python 코드 (연산자) 비교

SQL 문법을 알고 있는 사람은 쉽게 R을 배울 수 있음

유사한 형태로 데이터를 추출하면, 연산자 차이는 반복적으로 사용하면 익숙해짐

 

사용 데이터 : slam_dunk_total 데이터

Rstudio 데이터 가공 및 기초 분석 #2 (tistory.com)

 

Rstudio 데이터 가공 및 기초 분석 #2

table () 데이터의 고유한 값들의 빈도를 계산하여 테이블로 반환 벡터, 요인형 데이터, 문자열 등 다양한 형태의 데이터에 대해 빈도를 계산할 수 있음 기본 예제 eg_1

logistician.tistory.com

uniform_no name height weight blood type age position school
4 채치수 197 90 A 19 C 상북
5 권준호 178 62 A 19 SF 상북
6 이달재 164 NA NA 18 PG 상북
7 송태섭 168 59 B 18 PG 상북
8 신오일 170 NA NA 18 PG 상북
9 정병욱 180 NA NA 18 SF 상북
10 강백호 189 83 B 17 PF 상북
11 서태웅 187 75 AB 17 SF 상북
12 이호식 170 NA NA 17 SF 상북
13 이재훈 171 NA NA 17 PG 상북
14 정대만 184 70 A 19 SG 상북
15 오중식 162 NA NA 17 PG 상북
4 변덕규 202 90 NA 19 C 능남
5 허태환 183 NA NA 19 F 능남
6 안영수 174 62 NA 18 G 능남
7 정대협 190 79 NA 18 F 능남
8 백정태 170 62 NA 18 G 능남
13 황태산 188 80 NA 18 F 능남
11 하상태 188 NA NA 17 C 능남
15 박경태 165 NA NA 17 G 능남
... ... ... ... ... ... ... ...

※ 비교를 위한 용도이며, 코드는 작성자에 따라 다를 수 있음 

1. 상북고 (school이 상북) 선수 데이터 추출

R

# CSV 파일 읽기
slam_dunk_total <- read.csv("slam_dunk_total.csv")

# 'school'이 '상북'인 데이터 선택
selected_data <- data[slam_dunk_total$school == "상북", ]

# 선택된 데이터 출력
print(selected_data)
   uniform_no   name    height    weight     blood.type     age     position     school
1                4   채치수       197         90                 A          19          C            상북
2                5   권준호       178         62                 A          19         SF           상북
3                6   이달재       164        NA             <NA>       18         PG           상북
4                7   송태섭       168         59                 B          18         PG          상북
5                8   신오일       170        NA              <NA>      18         PG          상북
6                9   정병욱       180        NA              <NA>      18         SF          상북
7              10   강백호       189         83                 B         17         PF          상북
# tidyverse 파이프 연산자 활용

library (tidyverse)

selected_data2 <-  slam_dunk_total |>
                            filter (school == "상북")

# 선택된 데이터 출력
print(selected_data2)

SQL

-- slam_dunk_total.csv 파일을 데이터베이스 테이블로 로드하는 명령
-- 예: COPY player FROM 'slam_dunk_total.csv' WITH CSV HEADER;

-- 'school'이 '상북'인 데이터 선택

SELECT * FROM slam_dunk_total WHERE school = '상북';

python

import pandas as pd

# CSV 파일 읽기
slam_dunk_total = pd.read_csv("slam_dunk_total.csv")

# 'school'이 '상북'인 데이터 선택
selected_data = data[slam_dunk_total['school'] == '상북']

# 선택된 데이터 출력
print(selected_data)

2. position이 PG와 SG 선수 데이터 추출

R

# 'position'이 'PG'나 'SG'인 선수들 추출
selected_data <- data[slam_dunk_total$position %in% c("PG", "SG"), ]

# 선택된 데이터 출력
print(selected_data)
   uniform_no   name height weight blood.type age position school
3           6 이달재    164     NA       <NA>  18       PG   상북
4           7 송태섭    168     59          B  18       PG   상북
5           8 신오일    170     NA       <NA>  18       PG   상북
10         13 이재훈    171     NA       <NA>  17       PG   상북
11         14 정대만    184     70          A  19       SG   상북
12         15 오중식    162     NA       <NA>  17       PG   상북
# tidyverse 파이프 연산자 활용
selected_data2 <-  slam_dunk_total |>
                             filter (position %in% c( "PG", "SG")  )

# 선택된 데이터 출력
print(selected_data2)

SQL

-- 'position'이 'PG'나 'SG'인 선수들 추출

SELECT * FROM slam_dunk_total WHERE position IN ('PG', 'SG');

python

# 'position'이 'PG'나 'SG'인 선수들 추출
selected_data = data[slam_dunk_total['position'].isin(['PG', 'SG'])]

# 선택된 데이터 출력
print(selected_data)

 

3. 신장 (height)이 185 이상 190 미만인 선수 데이터 추출

R

# 'height'가 185 이상 195 미만인 데이터 추출
selected_data <- data[slam_dunk_total$height >= 185 & slam_dunk_total$height < 195, ]

# 선택된 데이터 출력
print(selected_data)
   uniform_no   name height weight blood.type age position school
7          10 강백호    189     83          B  17       PF   상북
8          11 서태웅    187     75         AB  17       SF   상북
16          7 정대협    190     79       <NA>  18        F   능남
18         13 황태산    188     80       <NA>  18        F   능남
19         11 하상태    188     NA       <NA>  17        C   능남
23          6 장권혁    190     81       <NA>  19        F   상양
24          7 임택중    191     84       <NA>  19        F   상양
25          8 오창석    193     85       <NA>  19        C   상양
28          5 고민구    191     80       <NA>  19        C   해남
32          6 신준섭    189     71       <NA>  18        F   해남
# tidyverse 파이프 연산자 활용
selected_data2 <-  slam_dunk_total |>
                             filter (height >= 185 & data$height < 195  )

# 선택된 데이터 출력
print(selected_data2)

SQL

-- 'height'가 185 이상 195 미만인 데이터 추출

SELECT * FROM slam_dunk_total WHERE height >= 185 AND height < 195;

python

# 'height'가 185 이상 195 미만인 데이터 추출
selected_data = data[(slam_dunk_total['height'] >= 185) & (slam_dunk_total['height'] < 195)]

# 선택된 데이터 출력
print(selected_data)

4. 학교(school)별 신장 (height)이 190 이상인 선수 수

R

# 'school' 별로 'height'가 190 이상인 학생 수 계산
result <- aggregate(height >= 190 ~ school, slam_dunk_total, sum)

# 결과 출력
print(result)
  school height >= 190
1   능남             2
2   산왕             3
3   상북             1
4   상양             4
5   풍전             1
6   해남             1
# tidyverse 파이프 연산자 활용
result2 <- slam_dunk_total |>
  filter(height >= 190) |>
  group_by(school) |>
  summarise( student_count = n() )

# 결과 출력
print(result2)

SQL

-- 'school' 별로 'height'가 190 이상인 학생 수 계산
SELECT school, COUNT(*) AS student_count
FROM slam_dunk_total
WHERE height >= 190
GROUP BY school;

python

l# 'school' 별로 'height'가 190 이상인 학생 수 계산
result = data[slam_dunk_total['height'] >= 190].groupby('school').size().reset_index(name='student_count')

# 결과 출력
print(result)

5. 신장 (height)  그래프 (예. Box Plot)

R

# 박스 플롯 생성
boxplot(slam_dunk_total$height, main="Height Box Plot")
# ggplot으로 박스 플롯 생성
ggplot(slam_dunk_total, aes(y = height)) +
  geom_boxplot() +
  ggtitle("Height Box Plot")

 

SQL

SQL로 데이터를 추출한 뒤, 외부 시각화 도구로 박스 플롯 생성
직접적으로는 불가

python

# 박스 플롯 생성
plt.boxplot(slam_dunk_total['height'])
plt.title("Height Box Plot")
plt.show()
# seaborn으로 박스 플롯 생성
sns.boxplot(x=data['height'])
plt.title("Height Box Plot")
plt.show()

R_엑셀_SQL 비교



유럽 사람들이 인접 국가의 언어를 쉽게 배우는 것 처럼
한 개의 분석 언어를 익히면, 다른 언도 쉽게 배울 수 있으며,
IT 전공자 및 개발자가 사용하는 SQL 기반으로 R이나 python을 쉽게 배우는 것처럼
R 코드를 배운다면, IT 비전공자여도 SQL도 해석 및 이해 가능


단, 동시에 2개의 프로그램 언어를 배우는 것은 혼란만 가중될 수 있음
어린이가 2개의 언어를 동시에 배우는 것과
어른이 2개의 언어들 동시에 배우는 것은 차이가 큰 것처럼

 

 

 

 

 

 

 

 

728x90