분류 전체보기
- 3-2. 결측값(결측치) 2019.02.14 1
- 3-1. 이상치 2019.02.14
- 02. 07 새로운 의료데이터 받기 2019.02.09
- 3. 통계적 추론과 가설검정, p-value 2019.02.05
- || ( 문자열 칼럼 concat)* and DATE (-)연산을 통해 만나이 계산* MSSQL과 비교해보기*** 2019.02.02
- 02. 01 첫 cdm 스터디 2019.02.01
- 2-2 R markdown ggplot2 ( plotly 올릴시 에러 ) 2019.02.01
- 2. R markdown( 변수별 EDA 및 abline 2가지 사용) 2019.02.01
- python random모듈 3개 정리 (randint, rand, randn) 2019.01.31 9
- SERIAL*( autoincrement 실용적인 대체) 2019.01.31
- ENUM* (순서를 가진 문자열범주 - ordinal) and NESTED SELECT*(집계결과는 따로받아, 해당테이블 SELECT 칼럼연산 or WHERE조건으로 사용) 2019.01.31
- DATE - timestamp 2019.01.31
- list, set comprehension 정리 2019.01.30
- HAVING* ( group by 결과물의 조건문 ) 2019.01.30
- DROP * ( with CASCADE ) and VIEW* ( with LOCAL / CASECADE CHECK OPTION ) 2019.01.30
3-2. 결측값(결측치)
결측값(결측치) in R
NA(Not Available)
, 결측치라고 하며 값이 표기되지 않은 값.- R에서 [행,열] 중 행 인덱싱 자리에
is.na(dataframe) + sum(결측치 개수), mean(결측률)
을 얻을 수 있다. * pandas : df.isnull().sum() , mean()
결측값(결측치)의 종류
EDA를 하면서 결측치가 있는 칼럼을 표
+ 시각화
하여 Random(관깊칼럼X) / No random(관깊칼럼O-> 범주별 대치, 예측)을 판단
해야한다.
Random
: 무작위로 정보가 없는 결측치, 다른변수별로 보면 결측비율도 달라진다. ->삭제(전체or부분)
or조건부 대치
or예측모형으로 해당변수 예측
모두가능
ex> 몸무게 결측치, 남자<여자의 결측 가능성이 높다. -> 범주별 대치
No random
: 결측값 자체가 (민감한 정보라서) 패턴을 가짐 ->관깊칼럼범주별 수치(평균/중앙값/최빈값)으로 대치
ex> 고소득자와 저소득자의 연봉은 결측치가 될 확률이 높다 ->관계 깊은 칼럼인 사는곳별 평균/중앙값/최빈값 or예측값으로 대치
결측치를 탐색하는 방법 2가지 (표+시각화)
표
:mice패키지
-> 결측치 1(아닌 것을 0)으로 표기한 뒤x 갯수
로 나타내어 조합별로도 확인가능시각화
1)cor(y)
: 결측치 1(아닌 것을 0)에 대해 이변수간의 상관관계로서 결측치를 나타낸다.
2)Vim패키지
: 결측치(빨간색)의 빈도 및 패턴을 시각화한다. 결측된 양을 scalebar로 나타내준다.
결측치 처리방법 3가지
삭제
1) List Wise Deletion : row가 어느 한 칼럼(변수)라도 missing이면 삭제 -> 간단하지만, sample size가 떨어져 power가 낮아진다.
2) Pair Wise Deletion : 관심있는 칼럼(변수)에 값이 있다면, 포함시킨다.대치(Imputation)
1) 최빈값(mode, qualitative) : 범주형에서 결측값이 발생시, 범주별 빈도가 가장 높은 값으로 대치한다. -> but bias가 많이 발생할 수 있다. ex> 남자, 여자 중에 남자의 빈도가 높다고 남자도 대치한다면, bias가 높아진다.
2) 중앙값(median) : 숫자형(연속형)에서 결측값제외한 중앙값으로 대치방법
3) 평균(mean) : 숫자형(연속형)에서 결측값제외한 평균으로 대치방법
4) Similar case imputation : 조건부 대치
5) Generalized Imputation : 회귀분석을 이용한 대치
예측모델(Prediction model)
1) 결측값이 없는 칼럼(변수)들로 구성된 dataset으로 -> 결측값이 있는 칼럼을 예측하게 한다.
2) 예측값으로 해당칼럼을 채워넣는다.가장 흔히 쓰는 방법
1) 하나라도결측이 있는 변수 제외한 dataset
생성
2)imputation한 dataset 2개
정도 생성 (mean or median / regression / KNN 등으로)
3) 1)과 2)의dataset 3개에 대해서 결과값이 서로 일관성 있음
을 보여준다. ->결측대치방법이 senvitivity하지 않다
는 것을 제시하는 것
결측값(결측치) 처리 가이드라인
10% 미만
:삭제
or대치
10 ~ 20%
:Hot deck
(매년자료->해당년자료 추정) orregression
ormodel based imputation
20 ~ 50% 이상
:regression
ormodel based imputation
50% 이상
: 해당칼럼(변수)자체 제거
결측값 삭제 or 대치의 한계점
삭제를 통해 n수가 달라진다 -> 집단의 특성이 달라질 수 있다. ->
missing rate(10%미만)
을 확인하고 삭제한다대치는 틀린값으로 대체될 수 있다는 가능성이 항상 존재한다
'한의대 생활 > └ 통계에 대한 나의 정리' 카테고리의 다른 글
3-4. Rmarkdown 후향적 코호트 연구와 Propensity Score Matching(PSM) (0) | 2019.02.16 |
---|---|
3-3 Rmarkdown 이상치와 결측치 (0) | 2019.02.16 |
3-1. 이상치 (0) | 2019.02.14 |
3. 통계적 추론과 가설검정, p-value (0) | 2019.02.05 |
2-2 R markdown ggplot2 ( plotly 올릴시 에러 ) (0) | 2019.02.01 |
3-1. 이상치
이상치(Outlier)에 대해
- 이상치 처리는 데이터 분석 중 가장 많은 시간이 소요된다.
- EDA & data cleaning, data preprocessing, data manupulation, data massage, data munging, data wrangling
이상치
정의 : 데이터 전체적인 패턴에서 동떨어져있는 관측 값
영향점
이라고도 불림.- 독립변수(x축)에 있는 이상치(영향점) :
지대점
- 종속변수(y축)에 있는 이상치(영향점) :
아웃라이어
- boxplot에서 가운데 box의 높이 : 3Q - 1Q =
IQR
, 가운데 50%를 의미 - boxplot에서 box양쪽 막대 : 3Q + 1.5*IQR =
Upper fence
, 1Q-1.5*IQR =Lower fence
- boxplot에서 Upper, Lower fence 보다 바깥에 있는 값 :
아웃라이어
단변수(boxplot)에서 안보이던 이상치(Outlier)가 이변수(산점도)에서 보일 수 있다.
- 반드시 그림으로 그려봐야한다.
EDA
를 통해 새로운 이상치를 발견할 수 있다.
- 종류 :
1)실수
에 의한 아웃라이어 : 수집시 오류 + 측정단위 오류 + 실험시 에러
2)자연(real연구대상)
적 발생 아웃라이어 : 직원들월급 중 임원들은 따로 빼서 분석해야함. 자연적으로는 너무 차이날 수 밖에 없음.
3)역코딩
에 의한 아웃라이어 : 설문지에 의도적으로 1번과 5번 성향을 바꿔놨는데, 데이터 분석시 고려안함
4)의도
적 아웃라이어 : 설문조사시 10대들은 알콜섭취량 일부러 낮게 적음
5)sampling
아웃라이어 : 표본 중에 우연히 이상치요소들이 포함 ex> 사람들 키 조사하는데 농구선수도 포함됨
이상치(아웃라이어)의 영향력
- 평균뿐만 아니라
분산(표준편차)가 엄청 커져
-> 엄청 불안정한 자료가 된다. - 중앙값(median)은 그나마 영향을 덜 받는다.
- 평균뿐만 아니라
이상치 발견의 방법
시각화
: 단변수 boxplot -> 이변수 scatter plotZ(표준정규)분포상 3sd이상 떨어진 값
들 : 3sd는 왼쪽2.5%이하
, 오른쪽97.5%이상
- 1sd사이 : 68.27%
- 2sd사이 : 95.45%
- 3sd사이 : 99.73%
도메인 knowledge
를 특정기준으로 두고 파악 : ex 수축기 혈압 120 ~ 160 벗어나는 값들
이상치 제거 방법
- 삭제 :
입력시 error
거나outlier수가 굉장히 적을 경우
는 그냥삭제
- 대치(Imputation) : 다른 값으로 변경
범주별 mean/median/mode
등으로 대치통계적모델링(종속변수로 취급하여, 다른변수들로 예측 후 대치)
Binning
(숫자의 분포를 범주로 매핑)
스케일링(scaling)
: 보통right skewed(캐글에서 0.75이상)
인 경우log
나square root(제곱근)
을 취한다정규화(normalization)
:MinMax
,Z-score
등으로 정규화시킨다.
'한의대 생활 > └ 통계에 대한 나의 정리' 카테고리의 다른 글
3-3 Rmarkdown 이상치와 결측치 (0) | 2019.02.16 |
---|---|
3-2. 결측값(결측치) (1) | 2019.02.14 |
3. 통계적 추론과 가설검정, p-value (0) | 2019.02.05 |
2-2 R markdown ggplot2 ( plotly 올릴시 에러 ) (0) | 2019.02.01 |
2. R markdown( 변수별 EDA 및 abline 2가지 사용) (0) | 2019.02.01 |
02. 07 새로운 의료데이터 받기
sql고수 효* 선생님께 sql을 다룰 수 있는 간단한 설명과 자료를 건네주셨다.
의료데이터이므로 민감한 자료라 보관을 잘하고 연습후 폐기를 잘해야할 것이다.
나는 이것을 sql로 EDA를 마치고 python으로 불러와서 EDA 및 feature engineering을 거친 뒤, 머신러닝 알고리즘으로 예측해보려는 시도를 해보겠다
보고서 작성이 금요일까진데,, 월요일부터 본격 시도를 하려고한다..
ㅠㅠ 시간이 많이 촉박하다..
'한의대 생활 > 본4 - SNUBI 인턴생활' 카테고리의 다른 글
02. 22 학부연구생인턴 프로그램 수료식 (0) | 2019.02.22 |
---|---|
02. 19 분석 피드백 (0) | 2019.02.20 |
02. 01 첫 cdm 스터디 (0) | 2019.02.01 |
01. 29 식권 대량구매 (0) | 2019.01.30 |
01. 24 Pandas세미나 듣고옴 (0) | 2019.01.24 |
3. 통계적 추론과 가설검정, p-value
통계적 추론 2가지
어떤 이론이 과학적이려면 반증 가능성
을 가져야한다.
반증가능성이란? 가설이 실험or관찰에 의해서 반증될 가능성
쉽게 말하자면, H1을 증명하기 어려우니 H0가 아니다로 증명
통계적 추론
1.추정
: 표본으로 모수 등 모집단에 대한 어떤 값
을 추즉하는 과정으로 추정값 + 오차범위
(표본오차, 신뢰구간) 같이 제시
- 추정 : 모집단의 평균이 30이다.
2.가설검정
: 표본으로 모집단에 대한 주장or가설의 옳고 그름을 판정
하거나 대립가설(H1)을 채택 or 귀무가설(H0)을 기각
- 검정 : 모집단의 평균이 30보다 클 것이다.
가설검정의 4가지 절차
1.알고있던 귀무가설(H0)
과 입증하고자하는 대립가설(H1)
세우기 - 보수적, 잘 알려진 것을 H0로 잡고, H0를 실험한다.
- 입증하고자하는 대립가설을 증명하기는 너무 어려우니 알고 있던 귀무가설이 참이라고 가정하고 실험해서 반증하자
- 반증의 기준은 알고 있던 H0의 결과(검정통계량)가 연구자가 정한 유의수준(H0실험 분포상 x축에 찍히는 임계치결정)보다 바깥쪽에 찍혀 검정통계량(H0의 결과)에 의한 유의 확률이 기각역에 포함되어 **우연에 의한것으로 판단** -> 입증하고자**하는 H1가 유의미하다는 것으로 반증**.
2.검정통계량
산출(H0가 참이라고 가정하고 한 실험에서 나온 결과 - 해당 분포 그래프 상 x축에 찍히는 점)
3.유의수준
결정 by 연구자 ( 분포상 임계치(-x축에 찍히는 점)와 기각역(-임계치보다 바깥쪽)을 결정)
- 유의수준은 연구자가 결정하는 것으로 H0로 실험한 결과를 우연이 아니라고 해줄 수 있는 한계치. 보통 p-value : 0.05
로 한다.
- 유의확률
은 H0로 실험한 결과 나오는 확률이다.
4.검정결과 해석
가설검정에 대하여
가설검정 자체는 보수적인 실험으로서 반증가능성을 실험한다.
먼저, 알고 있던 귀무가설(H0)는 실험전까지 맞고 판단하면서 살아간다.
다음, 입증하고자 하는 대립가설(H1)은 실험 후, 알고있던 귀무가설이 아니라는 충분한 근거(유의확률이 유의수준보다 적게나왔을 때)가 있을 때 채택한다.
통계적 추론(값 추정과 가설 검정)의 목적은 data로 의사결정을 내리는 것이다.
통계적 추론(값 추정과 가설 검정)에서의 통계적(statistical)이라는 말은 표본을 이용해서 추론한다는 말이다.
통계라는 말에는 항상 에러가 우연히 발생(error)가 있으니, 우연이 아니라 정말 의미가 있다(effect)를 근거로 통계 분석(통계적 추론 중 가설검정
)을 통해 시작한다.
즉, 실험 결과가 우연(error)냐 아니냐(effect)를 결정하는 것이 가설검정
이다.
가설검정의 용어
H0
: 알고 있던, 기존에 알려진 가설 =귀무가설
=> 유의확률(p-value) - (x축상 검정통계량, H0의 결과확률)가 유의수준(0.05)(x축상 임계치)보다 작을 때기각
-이것을 바탕으로표본을 이용해 실험
이 이루어진다. 분포, 그래프 전부다H0가 참이다라는 가정하에 그려진다.H1
: 입증하고자 하는, 알고자하는 가설 =대립가설
=> 유의확률(p-value)가 유의수준(0.05)보다 작을 때채택
연구자는 귀무가설을 기각하고 싶어하고, 대립가설을 채택하고 싶어 할 것이다.제 1종 오류(a)
: 귀무가설이 참인데 불구하고, 귀무가설을 기각 = 대립가설을 채택한 오류 => 제 2종 오류보다 심각 => 허용한계를 정해야함(보통 0.05)
-효과/차이가 없다(H0)가 참인데 불구하고 기각 + 효과/차이가 있다고 판단. => 엄청난 부작용 발생가능성유의 확률(p값,p-value, significance probability)
: 제 1종 오류가 발생할 확률 = 귀무가설이 참인데 불구하고 알고자하는 대립가설을 채택할 확률 -> 이것의 허용치가 유의수준 -> 유의수준 허용치 안에 들어온다면, H0(귀무가설)기각 H1(대립가설 채택).유의수준(Significant Level)
: <귀무가설이 참이다 가정 하에> 데이터를 기반으로한(표본을 이용한) 실험결과(검정통계량)가 항상 옳은 것이 아니므로연구가가 정한 유의확률(제1종오류가 발생할 확률 = 귀무가설이 참인데, 기각 + 대립가설을 채택하는 확률)의 최대허용한계, 최대값, 마지노선
. 보통은 0.05로 잡는게 관례 => 실험의 분포 x축에임계치(Critical value)
가 결정되며, 그 이하가H0의 기각역(Critical Region or reject region)
이 됨
-쉽게 말하면, 유의수준 0.05 = 100번 중 최대 5번까지는 실수(제1종오류=귀무가설 참인데 기각)가 발생하더라도 허용한다.
-유의확률 0.03 = 100번 중 3번 실수(H1를 채택) -> 100번 중 5번(유의수준 0.05) 안에 들었다. -> 귀무가설이 참이더라도 기각하고 대립가설 채택제 2종 오류(b)
: 귀무가설이 거짓인데 불구하고, 귀무가설을 기각하지 않은 오류 = 제 2종 오류(b)검정통계량(Test Statistic, M-)
: 귀무가설이 참이다는 가정 하에,표본을 이용
하여 계산된 통계량,실제 실험의 결과
=> 검정 통계량 이하의 확률이유의확률
이 됨
가설검정의 예시
H0 : A반 키의 평균은 160이다.
에 대해H1 : A반 키의 평균은 160이 아니다
를 입증하고 싶다.
1)가설설정
은 되었다. 2번째검정통계량
(H0 참이라는 가정하 실험해서 결과)을 구하기 위해, A반 학생 10명을 뽑아서 평균 키를 젠다
2)유의수준(0.05)
하에서 검정통계량(10명의 평균 키)을 바탕으로유의확률
을 계산한다
3) 기각역에 들어오면 H0 기각 = H1 채택한다.휴지가 300m인지 확인해보고싶다. (보수적, 잘알려진 H0 : 휴지의 평균길이는 300m임)
1) 가설설정 : H0 : 휴지의 평균길이 300m이다. H1 : 휴지의 평균길이가 300m이 아니다.
2) H0하에 검정통계량을 계산하기 위해서 휴지 10개의 길이를 제고 유의수준하에 유의확률을 확인한다
3) H0기각 = H1채택 하거나 H0를 그대로 기각하지않는다.숟가락이 잘 구부려진다 -> 나는 초능력자다( 보수적, 잘알려진 H0 : 나는 초능력자x : 내 능력 = 다른사람의 능력)
1) 가설설정 : H0 : 나의 능력 = 다른사람들의 능력(보통 숟가락30개 구부림) / H1 : 내 능력 != 다른사람들의 능력(30개보다 더 많이 구부릴 것이다)
2) H0하에서 10명과 함께 숟가락 구부린 횟수의 평균과 내 구부린 횟수의 평균을 비교하여, 검정통계량을 계산한다
3) 유의수준하에서 유의확률을 확인하여, H0 기각 ? 기각x ? 를 결정한다.듀라셀 vs 에너자이져의 수명 차이
1) 가설설정 : H0 : 듀라셀 수명 = 에너자이저 수명
2) H0하에서 10개의 평균 수명을 비교 실험하여 검정통계량 계산
3) 유의수준 하(H0실험의 t분포에서 0.05)에서 검정통계량에 의한 유의확률을 확인하여 H0 기각x or H1 채택 을 선택한다.
가설검정의 종류
양측검정
: H1 :Ma != Mb
으로서 실험결과분포의 양쪽(Ma > Mb
&Ma < Mb)
을 봐야한다.단측검정
: H1 :Ma > Mb
orMa < Mb
으로서 실험결과분포의 한쪽만 본다.
오늘날의 p-value
- 빅데이터 시대로서 n수가 늘어나서 -> 유의확률0.05 들어가는 검정통계량도 늘었다 ->
다 유의하다고 나옴
- p-value만 보기에는 문제가 생길 수 있다. ->
평균차이와 비율차이를 같이 제시
등 - 유의함을 넘어서 더 좁아진
유용함(MCID, The Minimal Clinically Important Change Score)
구간도 생김 - JAMA에서 발표한 임상의 확증적 연구 :
0.005
쓰자 - 미국통계학회(ASA) : 종합해서 판단하자.
'한의대 생활 > └ 통계에 대한 나의 정리' 카테고리의 다른 글
3-2. 결측값(결측치) (1) | 2019.02.14 |
---|---|
3-1. 이상치 (0) | 2019.02.14 |
2-2 R markdown ggplot2 ( plotly 올릴시 에러 ) (0) | 2019.02.01 |
2. R markdown( 변수별 EDA 및 abline 2가지 사용) (0) | 2019.02.01 |
2. 전처리시 체크2가지 및 EDA시 변수의 성격에 따른 분류 (0) | 2019.01.25 |
|| ( 문자열 칼럼 concat)* and DATE (-)연산을 통해 만나이 계산* MSSQL과 비교해보기***
문자열로 입력된 날짜를 임시로 만들고 년/월/일을 짤라놓은 뒤 || 을 이용해 년 월 일을 '-'로 연결한 뒤,다시 DATE타입으로 바꾸어 연산해보는 공부
- 칼럼을 생성하고 싶다면 : SELECT절에서 값 AS 칼럼명
- timestamp 1개로 년/월/일 3개로 나누기 : TOCHAR_( date or timestamp, ' date 기호 ')
- || : SELECT절에서 문자열칼럼 or 생성한문자열 을 concat해준다.
- 둘다 DATE타입일 경우, 마이너스 연산이 가능하다. 연산결과는 n days + 시간 -> int로 캐스팅해야 숫자로 사용( 나누기 365 등)할 수 있다.
- PosgreSQL에서 birthday를 만나이로 계산하는 순서(년/월/일)로 나뉘어있다고 가정 :
(1) || 을 통해 YYYY-MM-DD형태로 변환
(2) DATE타입으로 캐스팅
(3) NOW()현재날짜와 (-) 연산
(4) int타입으로 캐스팅
(5) /365해주기 - MSSQL에서 birthday를 만나이로 계산하는 순서( YYYY-MM-DD)로 나뉘었다고 가정 :
(1) DATEDIFF( day, 시작날짜, GETDATE()) / 365 로 자동연산
전처리
- 기존 테이블
SELECT에 < 한개의자료 AS 칼럼명 > 으로 새 칼럼을 생성한 뒤, INTO로 테이블 생성
- '문자열' AS 칼럼명 (text형으로 칼럼생성)
- NOW() AS 칼럼명 (timestamp형로 칼럼생성) 등등.. 다된다.
SELECT *, NOW() AS time INTO students_with_birthday FROM students;
time칼럼에 날짜 입력해주기
UPDATE students_with_birthday SET time = '1987-01-30' WHERE name ='Moe'; UPDATE students_with_birthday SET time = '1988-03-29' WHERE name ='Larry'; UPDATE students_with_birthday SET time = '1980-02-28' WHERE name ='Rolf'; UPDATE students_with_birthday SET time = '1987-06-27' WHERE name ='Anne'; UPDATE students_with_birthday SET time = '1991-02-26' WHERE name ='Robert'; UPDATE students_with_birthday SET time = '1958-01-26' WHERE name ='Jose';
- 날짜(YYYY-MM-DD)를 문자열 & 년/월/일 로 분리하여 칼럼 만들고, 확인되면 INTO 넣어서 필요한 칼럼들만으로 테이블로 만들기
SELECT *, TO_CHAR(time, 'YYYY') as year_of_birth, TO_CHAR(time, 'MM') as month_of_birth, TO_CHAR(time, 'DD') as day_of_birth FROM students_with_birthday
SELECT name, current_mood, TO_CHAR(time, 'YYYY') as year_of_birth, TO_CHAR(time, 'MM') as month_of_birth, TO_CHAR(time, 'DD') as day_of_birth INTO students_birthday FROM students_with_birthday SELECT * FROM students_birthday
문자열인 년/월/일 칼럼을 || 과 sep '-'로 붙히는 연습해보기
- 문자열칼럼 || '문자열' or 문자열 칼럼
SELECT year_of_birth FROM students_birthday -- 2019 SELECT year_of_birth||'-' FROM students_birthday -- 2019- SELECT year_of_birth||'-'||month_of_birth FROM students_birthday -- 2019-02 SELECT year_of_birth||'-'||month_of_birth||'-'||day_of_birth FROM students_birthday -- 2019-02-01
문자열 YYYY || MM || DD 를 concat(||)으로 붙힌 것을 CAST( AS DATE)으로 타입 변환하기 ( YYYY-MM-DD 형태 아니면 안됨 )
SELECT CAST( year_of_birth||'-'||month_of_birth||'-'||day_of_birth AS DATE),* FROM students_birthday
date타입으로 바꿨으면, 특정시간칼럼과 연산이 가능하다.
SELECT NOW() - CAST( year_of_birth||'-'||month_of_birth||'-'||day_of_birth AS DATE) FROM students_birthday
날짜(둘다 DATE여야함.) 차이결과는 days +시간으로 나온다. 이것을
int
로 다시 형변환하면, day숫자만 나온다. * NOW()는 date가 아니라 timestamp로서 다른 타입이니 또 캐스팅SELECT CAST( CAST(NOW() AS DATE) - CAST( year_of_birth||'-'||month_of_birth||'-'||day_of_birth AS DATE) AS INT) FROM students_birthday
day를 /365 로 나누면, 만나이(년수)가 나온다.
SELECT CAST( CAST(NOW() AS DATE) - CAST( year_of_birth||'-'||month_of_birth||'-'||day_of_birth AS DATE) AS INT) / 365 FROM students_birthday
'한의대 생활 > └ PostgreSQL' 카테고리의 다른 글
SERIAL*( autoincrement 실용적인 대체) (0) | 2019.01.31 |
---|---|
ENUM* (순서를 가진 문자열범주 - ordinal) and NESTED SELECT*(집계결과는 따로받아, 해당테이블 SELECT 칼럼연산 or WHERE조건으로 사용) (0) | 2019.01.31 |
DATE - timestamp (0) | 2019.01.31 |
HAVING* ( group by 결과물의 조건문 ) (0) | 2019.01.30 |
DROP * ( with CASCADE ) and VIEW* ( with LOCAL / CASECADE CHECK OPTION ) (0) | 2019.01.30 |
02. 01 첫 cdm 스터디
최* 선생님께서 postgesql 서버에 접속한 노트북으로 쿼리를 돌리는 경험을 하게 해주셨다.
다만 민감한 서버라 내가 직접 가지고 연습할수는 없는가보다.
SQL의 귀재 김**선생님 의 세미나를 3시간가량 들었는데 그것을 매일 1회씩 5번 정도 반복했다
처음에는 4시간 넘게 걸리던 것이 1시간 가량으로 줄어들어 익숙해졌다.
쿼리보는 눈이 생긴것 같다.
앞으로 남은 기간동안 잘 할 수 있으려나
쿼리결과만 받아서 어떻게 분석할지 고민해보기로 했다.
설날동안 그동안 pandas분석한 것을 복습해서 최대한 결과물을 만들어봐야겠다.
'한의대 생활 > 본4 - SNUBI 인턴생활' 카테고리의 다른 글
02. 19 분석 피드백 (0) | 2019.02.20 |
---|---|
02. 07 새로운 의료데이터 받기 (0) | 2019.02.09 |
01. 29 식권 대량구매 (0) | 2019.01.30 |
01. 24 Pandas세미나 듣고옴 (0) | 2019.01.24 |
01. 23 작성중이던 논문 통계 정리 (0) | 2019.01.23 |
2-2 R markdown ggplot2 ( plotly 올릴시 에러 )
2-2 ggplot - 산점도, bar차트, boxplot
ggplot - 산점도1
- 도화지 : g <- ggplot(data, aes( 칼럼명1, 칼럼명2 ))
- 그림1) 산점도 : g(data,aes(숫자1,숫자2)) + geom_point(aes( ))
- 그림의 aes안에 colour, shape = factor(범주칼럼)으로 범주별 확인가능
- 그림의 aes안에 size, alpha = 숫자형칼럼으로 scale범주별 확인가능
- 그림의 aes안에 colour가 숫자형칼럼(factor()도 x)인 경우, scale바의 옵션을 지정해줄 수 있다. scale_colour_gradient(low = “red”, high = “green” )도
# install.packages("ggplot2")
library(ggplot2)
# 데이터 준비
data(mtcars)
View(mtcars)
# 1. 도화지 그리기
ggplot(mtcars, aes(wt, mpg))
# 2. 도화지에 산점도 그리기 + 색/모양으로 범주별로 보기
ggplot(mtcars, aes(wt, mpg)) +
geom_point( aes( colour = factor(vs),
shape = factor(cyl)) )
# 3. 도화지에 산점도 그리기 + 색/모양으로 범주별 + *size로 숫자형 칼럼을 scale로
ggplot(mtcars, aes(wt, mpg)) +
geom_point(aes(colour = factor(vs),shape=factor(cyl),size=qsec))
# 4. 도화지 + 산점도 + 색/모양으로로 범주별 + size로 숫자형칼럼을 scale로 + alpha로 숫자형 칼럼을 scale로
#+ alpha
ggplot(mtcars, aes(wt, mpg)) +
geom_point(aes(colour = factor(vs),shape=factor(cyl),size=qsec,alpha=wt))
# 5. colour가 숫자형칼럼(factor()도 x)인 경우, scale바의 옵션을 지정해줄 수 있다.
ggplot(mtcars, aes(wt, mpg)) +
geom_point(aes(colour = disp,shape=factor(cyl),size=qsec,alpha=wt)) +
scale_colour_gradient(low = "red")
ggplot(mtcars, aes(wt, mpg)) +
geom_point(aes(colour = disp,shape=factor(cyl),size=qsec,alpha=wt)) +
scale_colour_gradient(low = "red",high="green")
산점도 2 - facet_grid( ~ )범주별로 그림쪼개서 보기
- 도화지는 변수에 담아둘 수 있다.
- 산점도가 겹치는 경우 alpha 를 통해 투명도를 준다.
- 범주별로 그림쪼개서 볼때, 앞의 범주( 범주칼럼 ~ .)는 가로방향으로 쪼갠다.
- 범주별로 그림쪼개서 볼때, 뒤의 범주( . ~ 범주칼럼)는 세로방향으로 쪼갠다.
- facet_grid( ~ )로 나눠봤을 때, 빈 그림이 존재하면 facet_wrap으로
앞범주 X 뒷범주의 조합별로 산점도를 그리자 + ncol 도 입력가능하다.
# mpg 데이터(내장)
View(mpg)
# 숫자칼럼2개 -> 산점도 도화지
g <- ggplot(mpg, aes(displ, hwy))
# 숫자들이 겹치느 경우, alpha를 주어 겹치는 부분을 나타낸다.
g + geom_point(alpha=1/3)
# facet_grid( ~ )로 범주칼럼을 주면 범주별로 앞(가로방향으로) , 뒤(세로방향으로) 쪼개서 볼 수 있다.
g + geom_point(alpha=1/3) + facet_grid(cyl ~ . )
g + geom_point(alpha=1/3) + facet_grid(. ~ cyl)
g + geom_point(alpha=1/3) + facet_grid(cyl ~ class)
# 만약 산점도가 범주별로 빈값이 존재한다면 -> facet_wrap( ~ , ncol=)을 쓰자.
# 앞 범주 X 뒷 범주의 조합으로 쪼개준다.
g + geom_point(alpha=1/3) + facet_wrap(cyl ~ class)
g + geom_point(alpha=1/3) + facet_wrap(cyl ~ class, ncol = 3)
ggplot - bar chart
- barchart는 범주별 빈도를 보는 것이다.
- 도화지는 ggplot(df, aes( facotr(범주칼럼) )) * 범주칼럼이라도 factor()로 싸준다.
- 그림안에 aes없이 바로 witdh = 로 너비를 조절한다 (높이는 빈도가 책임)
- 그림안의 aes()에 colour = factor(범주칼럼)으로 테두리색으로 범주별 범주빈도를 본다.
그림안의 aes()에 fill = factor(범주칼럼)으로 stacked된 막대색으로 범주별 범주빈도를 본다.
추가적인 + coord_flip() 으로 가로세로반전해준다.
# 범주칼럼1개에 대한 빈도 : geom_bar()
c<-ggplot(mtcars, aes(factor(cyl)))
c+geom_bar()
# bar의 너비 조절하기 witdh옵션
c + geom_bar(width=0.5)
# aes(colour = factor(범주칼럼))으로 테두리색으로 범주별 barchart(범주별 빈도)를 본다.
# 만약 같은 범주를 준다면, x축의 범주와 테두리색의 범주가 같을 것이다.
c + geom_bar(width = 0.5, aes( colour = factor(cyl) ) )
# aes(fill = factor(범주칼럼))으로 stacked로 나눠진 막대 색으로 범주별 barchart(범주별 빈도)를 본다.
c + geom_bar(width = 0.5, aes( colour = factor(cyl),
fill = factor(am)) )
c + geom_bar(width = 0.5, aes( colour = factor(cyl),
fill = factor(am)) ) + coord_flip()
ggplot - boxplot
- 기본 boxplot은 숫자형칼럼의 분포를 보는 것이나
- geom_boxplot()은 기본적으로 범주별 숫자칼럼의 분포를 보는 도화지를 aes에 그린다. ggplot( df, aes(범주칼럼, 숫자칼럼))
그림은 geom_boxplot()으로 그린다.
** 더이상 범주추가가 없는 경우 - width, color(테두리색), fill(박스색), outlier의 색/모양을 준다.
- ** 범주를 추가하고 싶은 경우 2가지 방법
- 그림안의 aes()안에 colour = factor() or fill = factor() 로 준다.
- facet_grid()로 범주별로 그림을 쪼개준다.
- 선을 추가하고 싶을때는 geom_hline() 혹은 geom_vline()을 + 한다(abline대체)
# 데이터 준비
setwd("C:/Users/is2js/python_da/deep analysis(논문용 설문지 분석)")
sens = read.csv('sens_for_r.csv', header = T)
# 데이터 확인 - 범주2, 숫자1
dim(sens)
## [1] 387 3
head(sens)
## Kind.of.medicinal.herbs Sensitivity Group
## 1 SA 0.95 Ph.D. of Herbology
## 2 SA 0.95 Ph.D. of Herbology
## 3 SA 1.00 Ph.D. of Herbology
## 4 SA 0.95 Ph.D. of Herbology
## 5 SA 0.90 Ph.D. of Herbology
## 6 SA 0.95 Ph.D. of Herbology
summary(sens)
## Kind.of.medicinal.herbs Sensitivity Group
## AC :129 Min. :0.000 KMD : 36
## AMC:129 1st Qu.:0.650 Ph.D. of Herbology: 18
## SA :129 Median :0.800 Undergraduates :333
## Mean :0.757
## 3rd Qu.:0.950
## Max. :1.000
str(sens)
## 'data.frame': 387 obs. of 3 variables:
## $ Kind.of.medicinal.herbs: Factor w/ 3 levels "AC","AMC","SA": 3 3 3 3 3 3 2 2 2 2 ...
## $ Sensitivity : num 0.95 0.95 1 0.95 0.9 0.95 1 1 0.95 0.95 ...
## $ Group : Factor w/ 3 levels "KMD","Ph.D. of Herbology",..: 2 2 2 2 2 2 2 2 2 2 ...
apply(is.na(sens), MARGIN = 2, FUN='sum')
## Kind.of.medicinal.herbs Sensitivity Group
## 0 0 0
# summarizeColumns(sens)
View(sens)
# 기본 범주-숫자형의 범주별 boxplot(숫자의 분포)
boxplot( Sensitivity ~ Group,
data= sens,
notch = TRUE,
col = "orange")
## Warning in bxp(list(stats = structure(c(0.1, 0.55, 0.825, 0.9, 1, 0.75, :
## some notches went outside hinges ('box'): maybe set notch=FALSE
# ggplot - geom_boxplot(범주칼럼, 숫자칼럼, fill = 범주칼럼 or 새로운범주칼럼)
g <- ggplot(sens, aes(Group, Sensitivity))
g + geom_boxplot()
# (더이상의 추가 범주가 없을 때!)barplot처럼 그림의 aes 바깥에서 바로 width + fill ='박스색', color='테두리색'을 그린다.
g <- ggplot(sens, aes(Group, Sensitivity))
g + geom_boxplot(width = 0.3, color = 'darkslategrey', fill ='orange')
# 아웃라이어들에 대한 색과 모양도 지정해줄 수 있다.
g + geom_boxplot(width = 0.3, color = 'darkslategrey', fill ='orange',
outlier.color = 'black',outlier.shape = 1)
# (추가범주 방법1) 그림안의 aes()에서 colour/fill를 준다는 것은 테두리/박스색 별로 범주를 추가해주는 것이다.
# 이때는, aes()바깥의 color, fill을 삭제해야한다.
g + geom_boxplot(width = 0.3, aes(colour = factor(Kind.of.medicinal.herbs)))
g + geom_boxplot(width = 0.3, aes(fill = factor(Kind.of.medicinal.herbs)))
# (추가범주 방법2) 그림을 짤라서 범주를 주고 싶다면 facet_grid를 쓴다.
g + geom_boxplot(width = 0.3, color = 'darkslategrey', fill ='orange') +
facet_grid(.~Kind.of.medicinal.herbs)
# ggplot에서 새로운 선을 주고 싶을 땐 geom_hline/geom_vline으로 추가해준다.
# 여기서는 facet_grid로 범주까지 나뉘어져있으니, 그 범주를 주어 3개다 그이게 한다.
# 라인의 방향에 따라 y/xintercept를 준다.
g + geom_boxplot(width = 0.3, color = 'darkslategrey', fill ='orange') +
facet_grid(.~Kind.of.medicinal.herbs) +
geom_hline(aes(yintercept = mean(Sensitivity), group = Kind.of.medicinal.herbs), colour = 'red')
g + geom_boxplot(width = 0.3, color = 'darkslategrey', fill ='orange') +
facet_grid(.~Kind.of.medicinal.herbs) +
geom_vline(aes(xintercept = mean(Sensitivity), group = Kind.of.medicinal.herbs), colour = 'green')
'한의대 생활 > └ 통계에 대한 나의 정리' 카테고리의 다른 글
3-1. 이상치 (0) | 2019.02.14 |
---|---|
3. 통계적 추론과 가설검정, p-value (0) | 2019.02.05 |
2. R markdown( 변수별 EDA 및 abline 2가지 사용) (0) | 2019.02.01 |
2. 전처리시 체크2가지 및 EDA시 변수의 성격에 따른 분류 (0) | 2019.01.25 |
1. R markdown(데이터경로, 불러오기, 5가지확인, summarizeColumns, mytable, mycsv) (0) | 2019.01.25 |
2. R markdown( 변수별 EDA 및 abline 2가지 사용)
- EDA(Explanantory Data analysis)
데이터 준비 및 확인
library(moonBook)
data(acs) # 급성 심근경색
#View(acs)
dim(acs)
## [1] 857 17
head(acs)
## age sex cardiogenicShock entry Dx EF height weight
## 1 62 Male No Femoral STEMI 18.0 168 72
## 2 78 Female No Femoral STEMI 18.4 148 48
## 3 76 Female Yes Femoral STEMI 20.0 NA NA
## 4 89 Female No Femoral STEMI 21.8 165 50
## 5 56 Male No Radial NSTEMI 21.8 162 64
## 6 73 Female No Radial Unstable Angina 22.0 153 59
## BMI obesity TC LDLC HDLC TG DM HBP smoking
## 1 25.51020 Yes 215 154 35 155 Yes No Smoker
## 2 21.91381 No NA NA NA 166 No Yes Never
## 3 NA No NA NA NA NA No Yes Never
## 4 18.36547 No 121 73 20 89 No No Never
## 5 24.38653 No 195 151 36 63 Yes Yes Smoker
## 6 25.20398 Yes 184 112 38 137 Yes Yes Never
str(acs)
## 'data.frame': 857 obs. of 17 variables:
## $ age : int 62 78 76 89 56 73 58 62 59 71 ...
## $ sex : chr "Male" "Female" "Female" "Female" ...
## $ cardiogenicShock: chr "No" "No" "Yes" "No" ...
## $ entry : chr "Femoral" "Femoral" "Femoral" "Femoral" ...
## $ Dx : chr "STEMI" "STEMI" "STEMI" "STEMI" ...
## $ EF : num 18 18.4 20 21.8 21.8 22 24.7 26.6 28.5 31.1 ...
## $ height : num 168 148 NA 165 162 153 167 160 152 168 ...
## $ weight : num 72 48 NA 50 64 59 78 50 67 60 ...
## $ BMI : num 25.5 21.9 NA 18.4 24.4 ...
## $ obesity : chr "Yes" "No" "No" "No" ...
## $ TC : num 215 NA NA 121 195 184 161 136 239 169 ...
## $ LDLC : int 154 NA NA 73 151 112 91 88 161 88 ...
## $ HDLC : int 35 NA NA 20 36 38 34 33 34 54 ...
## $ TG : int 155 166 NA 89 63 137 196 30 118 141 ...
## $ DM : chr "Yes" "No" "No" "No" ...
## $ HBP : chr "No" "Yes" "Yes" "No" ...
## $ smoking : chr "Smoker" "Never" "Never" "Never" ...
summary(acs)
## age sex cardiogenicShock entry
## Min. :28.00 Length:857 Length:857 Length:857
## 1st Qu.:55.00 Class :character Class :character Class :character
## Median :64.00 Mode :character Mode :character Mode :character
## Mean :63.31
## 3rd Qu.:72.00
## Max. :91.00
##
## Dx EF height weight
## Length:857 Min. :18.00 Min. :130.0 Min. : 30.00
## Class :character 1st Qu.:50.45 1st Qu.:158.0 1st Qu.: 58.00
## Mode :character Median :58.10 Median :165.0 Median : 65.00
## Mean :55.83 Mean :163.2 Mean : 64.84
## 3rd Qu.:62.35 3rd Qu.:170.0 3rd Qu.: 72.00
## Max. :79.00 Max. :185.0 Max. :112.00
## NA's :134 NA's :93 NA's :91
## BMI obesity TC LDLC
## Min. :15.62 Length:857 Min. : 25.0 Min. : 15.0
## 1st Qu.:22.13 Class :character 1st Qu.:154.0 1st Qu.: 88.0
## Median :24.16 Mode :character Median :183.0 Median :114.0
## Mean :24.28 Mean :185.2 Mean :116.6
## 3rd Qu.:26.17 3rd Qu.:213.0 3rd Qu.:141.0
## Max. :41.42 Max. :493.0 Max. :366.0
## NA's :93 NA's :23 NA's :24
## HDLC TG DM HBP
## Min. : 4.00 Min. : 11.0 Length:857 Length:857
## 1st Qu.:32.00 1st Qu.: 68.0 Class :character Class :character
## Median :38.00 Median :105.5 Mode :character Mode :character
## Mean :38.24 Mean :125.2
## 3rd Qu.:45.00 3rd Qu.:154.0
## Max. :89.00 Max. :877.0
## NA's :23 NA's :15
## smoking
## Length:857
## Class :character
## Mode :character
##
##
##
##
apply(is.na(acs), MARGIN = 2, FUN='sum')
## age sex cardiogenicShock entry
## 0 0 0 0
## Dx EF height weight
## 0 134 93 91
## BMI obesity TC LDLC
## 93 0 23 24
## HDLC TG DM HBP
## 23 15 0 0
## smoking
## 0
library(mlr)
## Loading required package: ParamHelpers
summarizeColumns(acs)
## name type na mean disp median
## 1 age integer 0 63.31155 11.69630382 64.00000
## 2 sex character 0 NA 0.33488915 NA
## 3 cardiogenicShock character 0 NA 0.06067678 NA
## 4 entry character 0 NA 0.36406068 NA
## 5 Dx character 0 NA 0.53325554 NA
## 6 EF numeric 134 55.83444 9.62296368 58.10000
## 7 height numeric 93 163.17539 9.07930672 165.00000
## 8 weight numeric 91 64.84373 11.35519114 65.00000
## 9 BMI numeric 93 24.28190 3.34669608 24.16104
## 10 obesity character 0 NA 0.33838973 NA
## 11 TC numeric 23 185.20024 47.77292477 183.00000
## 12 LDLC integer 24 116.58343 41.09484883 114.00000
## 13 HDLC integer 23 38.23501 11.08668982 38.00000
## 14 TG integer 15 125.23872 90.85259401 105.50000
## 15 DM character 0 NA 0.35472579 NA
## 16 HBP character 0 NA 0.41540257 NA
## 17 smoking character 0 NA 0.61260210 NA
## mad min max nlevs
## 1 13.343400 28.0000 91.00000 0
## 2 NA 287.0000 570.00000 2
## 3 NA 52.0000 805.00000 2
## 4 NA 312.0000 545.00000 2
## 5 NA 153.0000 400.00000 3
## 6 7.857780 18.0000 79.00000 0
## 7 7.413000 130.0000 185.00000 0
## 8 10.378200 30.0000 112.00000 0
## 9 3.011608 15.6157 41.42012 0
## 10 NA 290.0000 567.00000 2
## 11 42.995400 25.0000 493.00000 0
## 12 40.030200 15.0000 366.00000 0
## 13 10.378200 4.0000 89.00000 0
## 14 60.045300 11.0000 877.00000 0
## 15 NA 304.0000 553.00000 2
## 16 NA 356.0000 501.00000 2
## 17 NA 204.0000 332.00000 3
VIM 패키지의 VIM 라이브러리를 통한 null값 확인
# install.packages("VIM")
library(VIM)
## Loading required package: colorspace
## Loading required package: grid
## Loading required package: data.table
## VIM is ready to use.
## Since version 4.0.0 the GUI is in its own package VIMGUI.
##
## Please use the package to use the new (and old) GUI.
## Suggestions and bug-reports can be submitted at: https://github.com/alexkowa/VIM/issues
##
## Attaching package: 'VIM'
## The following object is masked from 'package:datasets':
##
## sleep
aggr(acs, prop = F, numbers = T)
범주형/숫자형 변수 나누어서 분석해주는 라이브러리 xda
# 범주형/숫자형 변수 확인을 위한 패키지 xda 설치
#https://github.com/ujjwalkarn/xda
# library(devtools)
# install_github("ujjwalkarn/xda")
# 설치방법 : 1) *관리자 권환으로실행 -> 2) 깃허브인스톨 패키지설치 -> 3) 깃허브인스톨라이브러리로 xda 를 다운 -> 4) xda 라이브러리 사용
# install.packages("githubinstall")
# library(githubinstall)
# githubinstall("xda")
# 사용
# library(xda)
# 데이터셋 자체에 대해서 범주형과 숫자형 변수(칼럼)들 자동분석
# bivariate(iris,'Species','Sepal.Length',n.bins=2)
# bivariate(iris,'Sepal.Length','Species')
범주형 변수 분석 (범주 -> 빈도 / 범주-범주 -> 빈도로 이루어진 교차표 )
- table()함수로 범주형 1개(단변수), 범주형 2개(이변수)를 빈도/교차표 생성
- 카이제곱검정 chisq.test( table = 교차표 )로 범주형변수 2개의 연관성 확인
- H0 : 서로 독립이다.
# 1. 범주형 단변수 분석
table(acs$Dx) # 범주별 빈도 확인
##
## NSTEMI STEMI Unstable Angina
## 153 304 400
prop.table( table(acs$Dx)) # 범주별 상대빈도 확인
##
## NSTEMI STEMI Unstable Angina
## 0.1785298 0.3547258 0.4667445
barplot( table(acs$Dx) ,
col = c("orange", "blue", "red") ) # 범주별 빈도 bar chart
# install.packages("qualityTools")
library(qualityTools)
## Loading required package: Rsolnp
##
## Attaching package: 'Rsolnp'
## The following object is masked from 'package:mlr':
##
## benchmark
## Loading required package: MASS
##
## Attaching package: 'qualityTools'
## The following object is masked from 'package:data.table':
##
## cube
## The following object is masked from 'package:stats':
##
## sigma
paretoChart(table(acs$Dx)) # 범주별빈도 + 누적합계 bar chart + line
##
## Frequency 400 304 153
## Cum. Frequency 400 704 857
## Percentage 46.7% 35.5% 17.9%
## Cum. Percentage 46.7% 82.1% 100.0%
##
## Frequency 400.00000 304.00000 153.00000
## Cum. Frequency 400.00000 704.00000 857.00000
## Percentage 46.67445 35.47258 17.85298
## Cum. Percentage 46.67445 82.14702 100.00000
paretoChart(table(acs$Dx),
showTable = F)
##
## Frequency 400 304 153
## Cum. Frequency 400 704 857
## Percentage 46.7% 35.5% 17.9%
## Cum. Percentage 46.7% 82.1% 100.0%
##
## Frequency 400.00000 304.00000 153.00000
## Cum. Frequency 400.00000 704.00000 857.00000
## Percentage 46.67445 35.47258 17.85298
## Cum. Percentage 46.67445 82.14702 100.00000
# 2. 범주형 이변수 분석
table(acs$sex, acs$Dx) # 범주-범주 분석- 범주별 빈도 교차표
##
## NSTEMI STEMI Unstable Angina
## Female 50 84 153
## Male 103 220 247
tab <-table(acs$sex, acs$Dx)
addmargins(tab) # 범주2개의 교차표에 sum을 표함시킨다.
##
## NSTEMI STEMI Unstable Angina Sum
## Female 50 84 153 287
## Male 103 220 247 570
## Sum 153 304 400 857
prop.table(tab) # 전체합에 대한 상대빈도 교차표
##
## NSTEMI STEMI Unstable Angina
## Female 0.05834306 0.09801634 0.17852975
## Male 0.12018670 0.25670945 0.28821470
prop.table(tab, 1) # 1= 가로에 있는 범주(sex)에 대한(분모) 상대빈도 교차표
##
## NSTEMI STEMI Unstable Angina
## Female 0.1742160 0.2926829 0.5331010
## Male 0.1807018 0.3859649 0.4333333
prop.table(tab, 2) # 2=0=세로에 있는 범주(Dx)에 대한 상대빈도 교차표
##
## NSTEMI STEMI Unstable Angina
## Female 0.3267974 0.2763158 0.3825000
## Male 0.6732026 0.7236842 0.6175000
chisq.test( table(acs$sex, acs$Dx)) # 2개 범주의 독립성 확인(H0 : 독립)
##
## Pearson's Chi-squared test
##
## data: table(acs$sex, acs$Dx)
## X-squared = 8.7983, df = 2, p-value = 0.01229
mycol <- c("skyblue", "blue") # 범주 2개에 대한 색 미리 지정
barplot( table(acs$sex, acs$Dx), # 앞에 넣은 범주가 범례가 된다.
col = mycol , main ="Segmented Bar Plot of Gender")
legend("topleft", c("females "," males "), col= mycol, pch = 16)
mycol<-c("skyblue", "blue","darkblue")
barplot(table(acs$Dx, acs$sex), col = mycol, main = "Segmented Bar Plot of Diagnosis")
legend("topleft", c("NSTEMI", "STEMI", "Unstable Angina"), col= mycol, pch = 16, inset =0.05)
숫자형 변수 분석
- 숫자형 변수는 분포를 확인해야하니 boxplot 이다.
- 숫자형 변수의 분포 확인2 - 정규분포확인 hist
# 1. 숫자형 단변수
summary(acs$TG)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 11.0 68.0 105.5 125.2 154.0 877.0 15
quantile(acs$TG, na.rm=T)
## 0% 25% 50% 75% 100%
## 11.0 68.0 105.5 154.0 877.0
IQR(acs$TG, na.rm=T)
## [1] 86
var(acs$TG, na.rm=T)
## [1] 8254.194
sd(acs$TG, na.rm=T)
## [1] 90.85259
stem(acs$TG) # 줄기-잎 플롯
##
## The decimal point is 2 digit(s) to the right of the |
##
## 0 | 12222222233333333333333333333333333333444444444444444444444444444444
## 0 | 55555555555555555555555555555555555555555555556666666666666666666666+220
## 1 | 00000000000000000000000000000000000000000000000111111111111111111111+151
## 1 | 55555555555555555555555555555555555666666666666666666666666666666777+55
## 2 | 000000001111111112222222222222222333344444444444
## 2 | 555556666666667778888899
## 3 | 000111223
## 3 | 5788899
## 4 | 1123
## 4 | 555669
## 5 | 4
## 5 | 58
## 6 | 2
## 6 | 58
## 7 |
## 7 |
## 8 | 0
## 8 | 8
#install.packages("mosaic")
library(mosaic)
## Loading required package: dplyr
##
## Attaching package: 'dplyr'
## The following object is masked from 'package:MASS':
##
## select
## The following objects are masked from 'package:data.table':
##
## between, first, last
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
## Loading required package: lattice
##
## Attaching package: 'lattice'
## The following object is masked from 'package:moonBook':
##
## densityplot
## Loading required package: ggformula
## Loading required package: ggplot2
## Loading required package: ggstance
##
## Attaching package: 'ggstance'
## The following objects are masked from 'package:ggplot2':
##
## geom_errorbarh, GeomErrorbarh
##
## New to ggformula? Try the tutorials:
## learnr::run_tutorial("introduction", package = "ggformula")
## learnr::run_tutorial("refining", package = "ggformula")
## Loading required package: mosaicData
## Loading required package: Matrix
##
## The 'mosaic' package masks several functions from core packages in order to add
## additional features. The original behavior of these functions should not be affected by this.
##
## Note: If you use the Matrix package, be sure to load it BEFORE loading mosaic.
##
## Attaching package: 'mosaic'
## The following object is masked from 'package:Matrix':
##
## mean
## The following object is masked from 'package:ggplot2':
##
## stat
## The following objects are masked from 'package:dplyr':
##
## count, do, tally
## The following object is masked from 'package:qualityTools':
##
## dotPlot
## The following object is masked from 'package:mlr':
##
## resample
## The following objects are masked from 'package:stats':
##
## binom.test, cor, cor.test, cov, fivenum, IQR, median,
## prop.test, quantile, sd, t.test, var
## The following objects are masked from 'package:base':
##
## max, mean, min, prod, range, sample, sum
dotPlot(acs$TG,pch=19,col=6) # Dot plot
hist(acs$TG, pch=19, col="lightgray") # 히스토 그램 with 평균, 중앙값
abline(v= mean(acs$TG,na.rm=T), col = " blue")
abline(v= median (acs$TG,na.rm=T), col = "green")
legend("topright", c("Mean", "Median"), pch = c(16,15), col = c("blue", "green"))
par(mfrow=c(1,2))
boxplot(acs$TG, notch = T, col="orange", main="TG (in original scale)")
boxplot(log(acs$TG), notch = T, col="orange", main="TG (in log scale)")
par(mfrow=c(1,1))
# 2. 숫자형 이변수
# 데이터 준비
data("iris")
attach(iris)
# 데이터 확인
library(mlr)
summarizeColumns(iris) # 4가지 숫자형 + 1가지 범주형
## name type na mean disp median mad min max
## 1 Sepal.Length numeric 0 5.843333 0.8280661 5.80 1.03782 4.3 7.9
## 2 Sepal.Width numeric 0 3.057333 0.4358663 3.00 0.44478 2.0 4.4
## 3 Petal.Length numeric 0 3.758000 1.7652982 4.35 1.85325 1.0 6.9
## 4 Petal.Width numeric 0 1.199333 0.7622377 1.30 1.03782 0.1 2.5
## 5 Species factor 0 NA 0.6666667 NA NA 50.0 50.0
## nlevs
## 1 0
## 2 0
## 3 0
## 4 0
## 5 3
boxplot(Sepal.Length, notch = TRUE, col = "grey") # 숫자형 단변수의 분포 boxplot
boxplot(Sepal.Length~Species, data=iris, notch = TRUE, col = "orange") # 범주별 숫자의 분포boxplot
# 숫자형 변수의 분포 확인2 - hist로 정규분폰지 보기
hist(Sepal.Length,
col = "grey",
main = "R default",
ylab = "Frequency",
freq = FALSE)
plot(iris[,-5]) # 산점도 행렬 기본
plot(iris,'Petal.Length') # 특정 숫자칼럼에 대한 산점도 행렬
pairs(iris[,-5], gap = 0) # 산점도행렬
pairs(iris[,-5], gap = 0, panel = panel.smooth) #산점도행렬 + 회귀라인
# 범주별 - 산점도(숫자-숫자) 행렬
# install.packages("mycor")
library(mycor)
plot(mycor(iris),type=1,groups=Species)
plot(mycor(iris),type=2,groups=Species) #hist추가
plot(mycor(iris),type=3,groups=Species) #상관계수와 fitting curve
abline의 2가지 이용기
- 숫자-숫자형의 산점도에서 나오는 회귀식 결과 or 절편(a)과 기울기(b)로 회귀선을 그림
- 수평(h) 혹은 수직(v)선을 추가로 그려줌
#abline-회귀식에서 나온 계수로 회귀선 그리기
plot (cars , xlim =c(0, 25) )
abline (a=-5, b=3.5 , col ="red ")
abline(lm(dist~speed,data=cars),col="green")
# 추가 수평/수직선 그리기
plot (cars , xlim =c(0, 25) )
abline (a=-5, b=3.5 , col ="red ")
abline (h= mean ( cars $ dist ), lty =2, col =" blue ")
abline (v= mean ( cars $ speed ), lty =2, col =" green ")
'한의대 생활 > └ 통계에 대한 나의 정리' 카테고리의 다른 글
3. 통계적 추론과 가설검정, p-value (0) | 2019.02.05 |
---|---|
2-2 R markdown ggplot2 ( plotly 올릴시 에러 ) (0) | 2019.02.01 |
2. 전처리시 체크2가지 및 EDA시 변수의 성격에 따른 분류 (0) | 2019.01.25 |
1. R markdown(데이터경로, 불러오기, 5가지확인, summarizeColumns, mytable, mycsv) (0) | 2019.01.25 |
1. 통계 - 기술통계와 추론통계 , 표본추출방법들 (0) | 2019.01.19 |
python random모듈 3개 정리 (randint, rand, randn)
numpy 의 np.random. randint
vs rand/randn
¶
np.random.seed seed를 통한 난수 생성
np.random.randint 균일 분포의 정수 난수 1개 생성
np.random.rand 0부터 1사이의 균일 분포에서 난수 matrix array생성
np.random.randn 가우시안 표준 정규 분포에서 난수 matrix array생성
np.random.shuffle 기존의 데이터의 순서 바꾸기
np.random.choice 기존의 데이터에서 sampling
np.unique 데이터에서 중복된 값을 제거하고 중복되지 않는 값의 리스트를 출력
np.bincount 발생하지 않은 사건에 대해서도 카운트를 해준다
import numpy as np
random.randint
와 np.random.randint : 모두 (시작, n-1) 사이의 랜덤숫자 1개
뽑아내기¶
np.random.randint(6) # 0 or 1 or ~ or 5 0부터 5까지 랜덤한 숫자 1개
np.random.randint(1, 20) # 1부터 19까지 랜덤숫자 1개
np.random.rand(m,n)
: 0 ~ 1의 균일분포 표준정규분포
난수를 matrix array
(m,n) 생성¶
np.random.rand(6)
np.random.rand(3,2)
np.random.randn(m,n)
: 평균0, 표준편차1의 가우시안 표준정규분포
난수를 matrix array
(m,n) 생성¶
np.random.randn(6)
np.random.randn(3, 2)
'빅데이터 관련 프로그래밍 > pythonic practice' 카테고리의 다른 글
[중급3] Decorator for 반복되는 내용을 함수에 입히기 (0) | 2019.05.15 |
---|---|
[중급2] 리스트를 사용을 위한 Map, Filter, Reduce (0) | 2019.05.15 |
[중급1] comprehension 연습 (0) | 2019.05.15 |
for문 유형 / 정수목과 나눈나머지 (0) | 2019.05.04 |
list, set comprehension 정리 (0) | 2019.01.30 |
SERIAL*( autoincrement 실용적인 대체)
총 정리
- SEQUENCE와 달리, CREATE할 필요없이 그냥 테이블 생성시 칼럼 TYPE에 SERIAL 지정해주면 된다.
- 단, INSERT INTO 시, 테이블명옆에 table( serial칼럼을 제외한 칼럼명들)을 명시해주고 입력해야한다.
만약, SERIAL 이외 칼럼 명시없이, 제외하고 입력하면 오류난다.
SERIAL
-- SERIAL type -- : postgreSQL에 없는 autoincrement를 SEQUENCE로 했었지만, 그럴 필요없이 쉽게할 수있는 type제공 -- (SEQUENCE START n -> SET -> OWNED BY 의 과정이 필요없어진다!) -- (1) TABLE 생성시 type으로 SERIAL만 주면 된다. 1부터 시작한다. CREATE TABLE test ( id SERIAL PRIMARY KEY, name character varying(255) ) -- (2) 입력시 id와 name 중 name만 주면 된다. INSERT INTO test(name) VALUES ('chojaeseong'); SELECT * FROM test
'한의대 생활 > └ PostgreSQL' 카테고리의 다른 글
|| ( 문자열 칼럼 concat)* and DATE (-)연산을 통해 만나이 계산* MSSQL과 비교해보기*** (0) | 2019.02.02 |
---|---|
ENUM* (순서를 가진 문자열범주 - ordinal) and NESTED SELECT*(집계결과는 따로받아, 해당테이블 SELECT 칼럼연산 or WHERE조건으로 사용) (0) | 2019.01.31 |
DATE - timestamp (0) | 2019.01.31 |
HAVING* ( group by 결과물의 조건문 ) (0) | 2019.01.30 |
DROP * ( with CASCADE ) and VIEW* ( with LOCAL / CASECADE CHECK OPTION ) (0) | 2019.01.30 |
ENUM* (순서를 가진 문자열범주 - ordinal) and NESTED SELECT*(집계결과는 따로받아, 해당테이블 SELECT 칼럼연산 or WHERE조건으로 사용)
총 정리
ENUM
- ENUM 생성 : CREATE TYPE 이넘명 AS ENUM( '순서범주1', '순서범주2', '순서범주3' ) 형식으로 생성
- 테이블 생성시, datatype으로 지정해주기
- INSERT INTO 시 ENUM에 속한 범주만 입력가능
- WHERE 절에 특정범주에 부등호(< or >)를 통해 여러범주를 필터링할 수 있다.
NESTED SELECT
- 집계하는 테이블에서는, 집계결과를 따로 칼럼을 보기 위해서는, GROUP BY 에 넣어주고 그 칼럼별 집계밖에 못보지만,
집계결과를 따로 NESTED SELECT(SubQuery)로 취급하면 -> SELECT문에서 연산에 사용 or WHERE의 조건으로 걸 수 있다.
cf) 서브쿼리는 줄을 바꿔주고 tab하나 넣는게 보통양식
cf) SELECT 집계연산 FROM 테이블 WHERE 조건 ---> 조건까지 만족하는 테이블 이후 집계가됨
cf) alias 칼럼명은 "" 쌍따옴표로 만들어주자.
ENUM
-- 1) ENUM -- (1) 새로운 dataTYPE을 만드는데 ENUM으로서 만들자. ENUM()안에 limited된 String value들을 정의해주면, -- ***넣은 순서대로 순서를 가지는*** 순서형 범주(Ordinal <-> Nomial명목형) 데이터 타입이 된다. CREATE TYPE mood AS ENUM('extremely unhappy', 'unhappy', 'ok', 'happy', 'extremely happy'); -- (2) 새로 생성한 ENUM type의 mood를 칼럼의 type으로 지정해서 테이블을 생성하자. CREATE TABLE students ( name character varying(255), current_mood mood ); SELECT * FROM students --mood type의 칼럼이 생김 INSERT INTO students VALUES ('Moe', 'hapy') -- ENUM 범주에 없는 값을 입력시키면 에러가 난다. INSERT INTO students VALUES ('Moe', 'happy') INSERT INTO students VALUES ('Larry', 'happy') INSERT INTO students VALUES ('Rolf', 'extremely unhappy') INSERT INTO students VALUES ('Anne', 'extremely happy') INSERT INTO students VALUES ('Robert', 'unhappy') INSERT INTO students VALUES ('Jose', 'happy') SELECT * FROM students -- (3) ENUM은 순서형 범주(Ordinal)로서, WHERE 절에서 value로 필터링 할 수 있다. -- enum을 이용하면, string형으로 순서를 줄 수 있어서, 회원등급을 메길 수 있고 -- 설문score도 적용시킬 수 있다. 등등 SELECT * FROM students WHERE current_mood > 'ok';
NESTED SELECTD
-- NESTED SELECT : 집계결과를, 집게테이블에서 WHERE문 or SELECT에 다 쓸 수 있다. -- 매우 유용함. 쿼리 안에 쿼리가 들어가는 구조 -- 예제1)보다 높은 가격의 item들 목록 -- 내가 한 것) SELECT AVG(price) FROM items -- 73.16125 SELECT * FROM items WHERE price > 73.16125 -- 좋은 것으나 안되는 것) SELECT * FROM items WHERE price > AVG(price) -- 또다른 조건을 줄때는 HAVING을 쓰나, Group by 된 상태만 된다. -- 정답1) NESETED SELECT를 이용해야만, 집계테이블에서, 집계결과를, WHERE문에 사용할 수 있다. -- (1) 평균(집계)결과값을 사용할 부분을 제외한 WHERE문 작성 SELECT * FROM items WHERE price > (); -- (2) 집계결과를 bracket()에 작성 SELECT * FROM items WHERE price > (SELECT AVG(items.price) FROM items); -- my) 이전에 했었던 아이템 목록중 가장 비싼 아이템 골라오기 SELECT * FROM items WHERE price = (SELECT MAX(price) FROM items); -- 예제2 ) 아이템들의 가격이 <아이템 평균가격>보다 얼마나 비싸거나 쌀까? -- 내가 한 것 ) SELECT * FROM items; SELECT AVG(price) FROM items; SELECT items.name, items.price, () FROM itesm; SELECT items.name, items.price, (SELECT AVG(price) FROM items) FROM items; SELECT items.name, items.price - (SELECT AVG(price) FROM items) FROM items; -- 정답 1) -- (1) 평균집계값을 () 으로 비워두고, 집계테이블에서 필요한 칼럼들을 SELECT -- 가격의 비교를 위해서는 빼야한다. numeric은 SELECT 란에서 바로 (-)된다. SELECT items.name, items.price - () FROM items; -- (2) 서브쿼리의 기본 형식은 라인을 바꿔주고, tab을 넣는 것이다. SELECT items.name, items.price - ( SELECT AVG(price) FROM items ) FROM items; -- 예제3 ) expensive_items아이템들의 가격이 -- 과 얼마나 차이나는가? -- 를 VIEW로 만들기 -- 내가 한 것) SELECT * FROM items; SELECT * FROM items WHERE price > 80; SELECT AVG(price) FROM items WHERE price > 80; -- 155.163 : FROM WHERE이후 --> WHERE절로 필터링 SELECT AVG(price) FROM items; --73.16 SELECT items.name, items.price - () FROM items; SELECT items.name, items.price - ( SELECT AVG(price) FROM items WHERE price > 80 ) FROM items; -- 내가 catch못한 것 : 80달러보다 비싼 아이템의 평균값만 구하고, -- 그 이후 바깥의테이블에서는 80달러보다 비싸다는 WHERE를 안달아줘서, 모든 items들이 다 나왔음. -- 문제를 잘못받아적음. 기본적으로 expensive 아이템가격들의 expensive아이템의 평균과의 차이 -- ***FROM WHERE 필터링 이후--> SELECT의 집계연산이 이루어진다. -- 정답3 ) -- (1) 80달러보다 비싼 아이템의 평균 = WHERE 절까지 거친 테이블에 집계함수가 일어남 SELECT AVG(items.price) FROM items WHERE price > 80; -- (2) 다른칼럼들과 함께 + price - (1) 의 차이 SELECT하기 + WHERE 절 안빠트리기 SELECT *, items.price - ( ) FROM items WHERE price > 80; -- (3) NESTED SELECT 넣어주기 SELECT *, items.price - ( SELECT AVG(items.price) FROM items WHERE price > 80 ) FROM items WHERE price > 80; -- (4) VIEW로 만들기 CREATE VIEW expensive_items_diff AS SELECT *, items.price - ( SELECT AVG(items.price) FROM items WHERE price > 80 ) FROM items WHERE price > 80; -- (5) VIEW SELECT해보기 SELECT * FROM expensive_items_diff -- (6) 칼럼이름이 없어서, 다시 DROP후 서브쿼리 ()끝나고 AS로 칼럼명 " "로 alias 정의해주기 DROP VIEW expensive_items_diff; CREATE VIEW expensive_items_diff AS SELECT *, items.price - ( SELECT AVG(items.price) FROM items WHERE price > 80 ) AS "average_diff" FROM items WHERE price > 80; SELECT * FROM expensive_items_diff;
'한의대 생활 > └ PostgreSQL' 카테고리의 다른 글
|| ( 문자열 칼럼 concat)* and DATE (-)연산을 통해 만나이 계산* MSSQL과 비교해보기*** (0) | 2019.02.02 |
---|---|
SERIAL*( autoincrement 실용적인 대체) (0) | 2019.01.31 |
DATE - timestamp (0) | 2019.01.31 |
HAVING* ( group by 결과물의 조건문 ) (0) | 2019.01.30 |
DROP * ( with CASCADE ) and VIEW* ( with LOCAL / CASECADE CHECK OPTION ) (0) | 2019.01.30 |
DATE - timestamp
총 정리
# TO_CHAR() : timestamp -> 문자열 or 영어로표현된 문자열로
- 현재시간 : MSSQL : GETDATE() / PostgreSQL : NOW()
- 날짜-> 문자열로 변환 : MSSQL : CONVERT( datatype, 시간(시간칼럼), date type number) / PostgreSQL : TO_CHAR( 시간(시간칼럼) , 'date type' )
- TO_CHAR( , )에 들어가는 datetype에서, YYYY=yyyy, MM=mm, DD=dd, HH=hh 대소문자 구분안하고 년/월/일/시이다.
- 분(minute)는 MI = mi
--위는 TIMESTAMP 형식 : [ YYYY-MM-DD HH:MI:SS ]
--아래에서는 MM과 DD 대신 --> [ 요일(FMDAy) - 일의 th형식 + 월의 영어표현(FMMonth) ] -----
[ FMDay FMDDth FMMonth, YYYY HH:MI:SS] - 요일은 Day = day = DAY 가 있다. 그러나 공백을 제거하기 위해서는 FM을 붙힌 FMDay = FMDAY = FMday
- 일의 th 표현은 DDth = ddth이다.
- 월의 영어표현은 FMMonth = FMMONTH = FMmonth 이다.
# TO_TIMESTAMP() : 문자열 -> timestamp 로
- TO_TIMESTAMP( '문자열로 표현된 시간' , ' 그 문자열의 DATE TYPE 형식' )을 넣어주면, timestamp로 변환
TIMESTAMP
-- DATE -- date는 많은 문제가 있다. -- 1) datetime의 형태가 너무 많다. ex> 2019-01-30 or 01-30-2019 or 01. 30. 2019 -- 2) timezone개념이 붙어있다. ex> GMT, RUSSIAN, UTC 등등 장소에 따라 current time이 달라진다. -- >> 추천하는 방법 : SQL에는 TIMEZONE을 입력하지 않고, python 등 어플리케이션 단에서 TIMEZONE을 적용한다. -- PostgreSQL의 메인 date 타입 4가지 : timestamp, date, time, interval -- 1) timestamp -- ISO 8601 standard date 타입 in DB. YYYY-MM-DD HH:mm:ss -- pgSQL의 default 형식으로 많은 문제를 예방할 수 있음. SELECT timestamp '2019-01-30 13:30:45'; -- 2) timestamp to string -- (1) NOW()로 현재시간을 가져온다 <--> MSSQL의 GETDATE() or DATEDIFF( 간격, datetime, GETDATE()) -- (2) TO_CHAR( timestamp, 'DD' 등 날짜포맷 ); 으로 문자열로 전환 <--> MSSQL의 CONVERT( type, datetime, style) SELECT NOW(); --MSSQL에서는 GETDATE() 였다! SELECT TO_CHAR( NOW(),'DD' ); -- MSSQL의 CONVERT( type, datetime, style) or DATEDIFF( 간격, datetime, GETDATE()) SELECT TO_CHAR( NOW(),'dd' ); -- text 30 SELECT TO_CHAR( NOW(),'MM' ); SELECT TO_CHAR( NOW(),'mm' ); -- text 01 SELECT TO_CHAR( NOW(),'YYYY' ); SELECT TO_CHAR( NOW(),'yyyy' ); -- text 2019 SELECT TO_CHAR( NOW(), 'DD-MM-YYYY') -- text 30-01-2019 SELECT TO_CHAR( NOW(), 'DD-MM-YY') -- text 30-01-19 ==> confusing SELECT TO_CHAR( NOW(), 'DD-MM-YYYY HH') -- text 30-01-2019 02 SELECT TO_CHAR( NOW(), 'DD-MM-YYYY HH:MI'); -- pgSQL에서는 MM,mm month / MI :minute -- text 30-01-2019 02:28 SELECT TO_CHAR( NOW(), 'DD-MM-YYYY HH:MI:SS'); -- text 30-01-2019 02:28:08 SELECT TO_CHAR( NOW(), 'Day, DD-MM-YYYY HH:MI:SS'); -- text Wednesday, 30-01-2019 02:28:08 -- 만약 토요일이면, Saturday , 형식으로 빈칸이 하나 발생한다 그걸 제고 하고 싶다면 Day앞에 FM을 쓴다. SELECT TO_CHAR( NOW(), 'FMDay, DD-MM-YYYY HH:MI:SS'); -- text Wednesday, 30-01-2019 02:28:08 SELECT TO_CHAR( NOW(), 'FMDay Month, DD-MM-YYYY HH:MI:SS'); -- text Wednesday January , 30-01-2019 02:28:08 SELECT TO_CHAR( NOW(), 'FMDay FMMonth, DD-MM-YYYY HH:MI:SS'); -- text Wednesday January, 30-01-2019 02:28:08 --날짜를 3th 4th 형식으로도 줄 수 있다. SELECT TO_CHAR( NOW(), 'FMDay DDth FMMonth, DD-MM-YYYY HH:MI:SS'); -- text Wednesday 30th January , 30-01-2019 02:28:08 -- 이제 DD-MM 을 제거해서 보자. SELECT TO_CHAR( NOW(), 'FMDay DDth FMMonth, YYYY HH:MI:SS'); -- text Wednesday 30th January, 2019 02:28:08 -- 3) 이제 TO_TIMESTAMP( '마지막에 작성한 양식의 string' , 'string과 똑같은 양식의 날짜포맷' ); -- 를 통해 sting을 timestamp로 바꿀 수 있다. SELECT TO_TIMESTAMP('Wednesday 30th January, 2019 02:28:08', 'FMDay DDth FMMonth, YYYY HH:MI:SS'); -- 4) string양식이 ISO8601 이었으면, 그 string에 맞게 양식을 적어주면, timestamp로 변한다 SELECT TO_TIMESTAMP('2019-01-30 02:28:08', 'YYYY-DD-MM HH:MI:SS');
'한의대 생활 > └ PostgreSQL' 카테고리의 다른 글
SERIAL*( autoincrement 실용적인 대체) (0) | 2019.01.31 |
---|---|
ENUM* (순서를 가진 문자열범주 - ordinal) and NESTED SELECT*(집계결과는 따로받아, 해당테이블 SELECT 칼럼연산 or WHERE조건으로 사용) (0) | 2019.01.31 |
HAVING* ( group by 결과물의 조건문 ) (0) | 2019.01.30 |
DROP * ( with CASCADE ) and VIEW* ( with LOCAL / CASECADE CHECK OPTION ) (0) | 2019.01.30 |
SEQUENCE* ( autoincrement대체 ) and INDEX* ( WHERE서치를 문자열에서 빠르게 내부binary파일생성) (0) | 2019.01.30 |
list, set comprehension 정리
리스트 속 요소들을 변환한 리스트를 반환받는 법
- 변환될 빈 리스트 생성 -> for문 돌면서 처리 -> 각각 append
- list comprehension
- list ( map ( lambda x: , list ) )
리스트 속 요소들을 필터링한 리스트 반환받는 법
- list comprehenshion + if
1) [ xif 조건1 else 조건 2
for in ]
2) [ x for inif 조건1
] - list ( filter(lambda x: , list ) )
리스트 vs set
- list() : [1, 2, 3] or [] 로 생성하면 append한다
- set() : {1, 2, 3} 로 생성하면 add한다.
- { } 로 생성은 빈 딕셔너리다 ! set이 아니다! set의 양쪽 구성만 { }
리스트 속 요소들을 변환한 set을 반환받는 방법
- { set comprehension for in 리스트 }
'빅데이터 관련 프로그래밍 > pythonic practice' 카테고리의 다른 글
[중급3] Decorator for 반복되는 내용을 함수에 입히기 (0) | 2019.05.15 |
---|---|
[중급2] 리스트를 사용을 위한 Map, Filter, Reduce (0) | 2019.05.15 |
[중급1] comprehension 연습 (0) | 2019.05.15 |
for문 유형 / 정수목과 나눈나머지 (0) | 2019.05.04 |
python random모듈 3개 정리 (randint, rand, randn) (9) | 2019.01.31 |
HAVING* ( group by 결과물의 조건문 )
총정리
- HAVING은 GROUP BY 끝난 쿼리문에서 조건을 추가적으로 달 수 있다.
- HAVING은 1차 처리된 칼럼(COUNT()등)을 조건을 걸고 싶을 땐, alias사용이 안된다.
HAVING
-- 내장함수 & HAVING -- 내장함수의 종류 : -- COUNT(), SUM() -- 예제 ) 고객별 구매횟수 ( 횟수, 건수 : 해당 테이블의 id를 카운트 해버리면 된다) SELECT customers.first_name, customers.last_name, COUNT(purchases.id) FROM customers JOIN purchases ON customers.id = purchases.customer_id GROUP BY customers.id -- AVG() -- 예제 ) 아이템의 가격 평균 SELECT AVG(items.price) FROM items; -- 예제 ) 구매된(join으로 교집합) 아이템 가격의 평균 SELECT * FROM items INNER JOIN purchases ON items.id = purchases.item_id; SELECT AVG(items.price) FROM items INNER JOIN purchases ON items.id = purchases.item_id; -- 1) 구매된 아이템 중 가격 TOP 1 을 구하는 첫번째 : JOIN 구매된 아이템 -> ORDER BY -> LIMIT SELECT * FROM items INNER JOIN purchases ON items.id = purchases.item_id; SELECT items.name, items.price FROM items INNER JOIN purchases ON items.id = purchases.item_id SELECT items.name, items.price FROM items INNER JOIN purchases ON items.id = purchases.item_id ORDER BY items.price DESC LIMIT 1; -- 2) 구매된 아이템 가격 TOP 1을 구하는 두번째 : JOIN 구매된 아이템 -> MAX() ? -- : 집계테이블이 되어, 같은 테이블 내 칼럼선택(items.name)을 못함 -- 만약, 다른컬럼(items.name)도 같이보려고, 집계함수 앞에 SELECT 시 -- ~별 기준이 되어버려서, 각 items.name 별 최대값들이 여러 row로 나옴. SELECT MAX(items.price) FROM items INNER JOIN purchases ON items.id = purchases.item_id; -- 집계테이블로서 1개 칼럼밖에 못봄 SELECT items.name, MAX(items.price) FROM items INNER JOIN purchases ON items.id = purchases.item_id GROUP BY items.name;-- 하나더보려고 select + groupby에 넣으면 기준테이블이 되어 각 아이템별로 최대값이 되어버림 -- 3) HAVING = GROUP BY + 집계함수 결과에 filter링 (집계함수의 WHERE절) -- (1) 고객별 구매횟수를 위에서 작성했떤 것 복사해오자. SELECT customers.first_name, customers.last_name, COUNT(purchases.id) FROM customers JOIN purchases ON customers.id = purchases.customer_id GROUP BY customers.id -- (2) GROUPBY + 집계함수의 결과에서 HAVING을 이용하여 다시 3개이상의 구매자만 걸러내보자. -- *** 이때, 집계한칼럼의 alias로는 HAVING에서 조건을 걸 수 없다. -- *** 1차 작업물이 SELECT 문에 있을시 -> 이후 사용은 그 문장 그대로! SELECT customers.first_name, customers.last_name, COUNT(purchases.id) AS purchase_count FROM customers JOIN purchases ON customers.id = purchases.customer_id GROUP BY customers.id HAVING purchase_count > 2; -- alias 사용시 오류 SELECT customers.first_name, customers.last_name, COUNT(purchases.id) AS purchase_count FROM customers JOIN purchases ON customers.id = purchases.customer_id GROUP BY customers.id HAVING COUNT(purchases.id) > 2; -- 4) 다음에 같은작업(고객별 구매횟수가 가장 많은 사람 뽑기)할일이 있다면, VIEW로 만들어보자.
'한의대 생활 > └ PostgreSQL' 카테고리의 다른 글
ENUM* (순서를 가진 문자열범주 - ordinal) and NESTED SELECT*(집계결과는 따로받아, 해당테이블 SELECT 칼럼연산 or WHERE조건으로 사용) (0) | 2019.01.31 |
---|---|
DATE - timestamp (0) | 2019.01.31 |
DROP * ( with CASCADE ) and VIEW* ( with LOCAL / CASECADE CHECK OPTION ) (0) | 2019.01.30 |
SEQUENCE* ( autoincrement대체 ) and INDEX* ( WHERE서치를 문자열에서 빠르게 내부binary파일생성) (0) | 2019.01.30 |
CREAT TABLE*(primary key, references) and INSERT INTO (0) | 2019.01.29 |
DROP * ( with CASCADE ) and VIEW* ( with LOCAL / CASECADE CHECK OPTION )
총 정리
- DROP TABLE IF EXIST 테이블명
- 종속관계가 있는 테이블은, 참조하고 있는 테이블부터 지워야 삭제 가능하나, 종속관계를 끊고 삭제하려면 DROP TABLE 테이블명 CASCADE;
VIEW정리
- VIEW 생성 : CREATE VIEW 뷰명 AS groupby복잡한 쿼리문 을 통해 updatable한 테이블을 생성할 수 있음.
- VIEW 조회 : SELECT * FROM 뷰명 으로 테이블조회하듯이 조회한다.
- VIEW 삭제 : DROP VIEW 뷰명
- VIEW를 조회할 때 WHERE / ORDER BY달고 조회가능 /
- VIEW + WHERE 절 달아서 새로운 VIEW 생성가능
- VIEW생성시 AS쿼리문에 1) * 모든칼럼 선택한상태 + 2) * group by 등 집계안한 상태 + 3)WHERE문 정도 라면 : INSERT INTO VIEW 로 값 대입 가능, 특별한 옵션이 없다면 WHERE조건 만족못해도 원본테이블에 들어감
- WITH LOCAL CHECK OPTION으로 VIEW생성시, 해당WHERE절 조건만족못하는 것은 INSERT INTO VIEW로 대입 불가능
- view1를 이용해 view2를 만든 상태에서
(1) view1에 local옵션이 없고 & view2 local옵션만 있다면 ==> view2옵션만 체크한다.
(2) view1에 local옵션이 있고 & view2 local옵션있다면 ==> view1, view2 둘다 체크한다. ( 각 view가 local있다면, 다 체크 )
(3) view1에 local옵션이 없고 & view2 CASCADED 옵션이 있다면 ==> view1, view2 둘다체크한다. (마지막 view가 cascaded옵션있다면, 다 체크)
DROP TABLE 옵션 : CASCADE vs CASCADED : VIEW를 포함한 VIEW에서 2개 모두 WHERE절 조건 체크 옵션
DROP
-- DROP TABLE -- 1) videos테이블에서 users를 참조하고 있는 상황이므로 바로 삭제가 안된다. DROP TABLE public.users; -- 2) 강제로 삭제하는 방법은 뒤에 CASCADE를 붙혀 -> 다른테이블과의 관계를 끊는 것이다. DROP TABLE public.users CASCADE; -- 3) 관계는 끊어져도 기존에 연결된 값들은 유지되어있다. -- videos 테이블의 정보를 보면, CONSTRAINT fkey정보가 업어져있다. SELECT * FROM videos; -- 4) 만약, videos테이블을 먼저 DROP한다면, uses테이블도 바로 DROP 될 것이다. DROP TABLE public.videos; -- 5) 없는 테이블을 삭제하는 오류를 줄이고 싶다면 DROP TABLE <--> 테이블명 사이에 IF EXISTS 를 준다. -- 테이블을 생성하기 전에 적어줘도 좋은 팁이 된다. DROP TABLE IF EXISTS public.videos; -- 6) DROP TABLE/DATABASE/SEQUENCE/VIEW 등이 다 DROP이 가능하다.
VIEW
-- VIEW & INSERT VIEW without groupby & WITH LOCAL/CASCADE CHECK OPTION -- 1) view없이 고객들이 소비한 전체 돈 보기 by GROUP BY -- customers별 목록이 1 row로 나타나도록 id로 groupby + 기준테이블 칼럼들은 막 select + 집계테이블은 칼럼없이 sum()으로 1 row로 집계했다. SELECT customers.first_name, customers.last_name, SUM(items.price) FROM customers INNER JOIN purchases ON customers.id = purchases.customer_id INNER JOIN items ON purchases.item_id = items.id GROUP BY customers.id -- 2) 매번 groupby를 할게 아니라, VIEW를 이용해 해당 결과를 저장하자. -- CREATE VIEW + view이름 + AS + 저장할 쿼리문 형태이다. CREATE VIEW total_revenue_per_customer AS SELECT customers.first_name, customers.last_name, SUM(items.price) FROM customers INNER JOIN purchases ON customers.id = purchases.customer_id INNER JOIN items ON purchases.item_id = items.id GROUP BY customers.id -- 3) 마치 테이블처럼 SELECT할 수 있다. SELECT * FROM total_revenue_per_customer -- 4) DROP VIEW view이름으로 삭제할 수 있다. DROP VIEW total_revenue_per_customer -- 5) 다시 view를 만드는데, groupby 의 기준이된 customers.id도 같이 SELECT한 view를 만들자 -- 새로운 테이블로 보는데, id칼럼이 없기 때문...? -- 이 아니라,, 새로운 구매정보를 늘릴 때 view는 어떻게 변하는지 보기 위해서다. CREATE VIEW total_revenue_per_customer AS SELECT customers.id, customers.first_name, customers.last_name, SUM(items.price) FROM customers INNER JOIN purchases ON customers.id = purchases.customer_id INNER JOIN items ON purchases.item_id = items.id GROUP BY customers.id SELECT * FROM total_revenue_per_customer; -- 6) VIEW의 결과에 없는 customers 중에 한명이 item을 구매하도록 해보자. -- 구매정보를 늘이려면 purchases테이블에 추가해야한다. SELECT * FROM total_revenue_per_customer; --1,3,4,5는 구매했었음. SELECT * FROM customers; --남은건 2번 고객 SELECT * FROM items; --아이템은 아무거나.. 여기서 6번 아이템 SELECT * FROM purchases; -- 구매번호는 10번까지 차있구나. INSERT INTO purchases -- 구매번호 11, item_id 6번, customer_id 2번 VALUES (11, 6, 2); -- 7) 기존에 저장한 VIEW를 다시 보자. -- customers.id 2번이 추가되었다! / 만약 기존고객이 구매정보를 늘렸으면, sum이 증가할 것이다! -- VIEW는 결과가 아니라 쿼리문 자체를 저장해서 updatable한 테이블을 생성해주는 것 SELECT * FROM total_revenue_per_customer; -- 8) VIEW로 저장한 쿼리문에는 WHERE문도 달 수 있다. SELECT * FROM total_revenue_per_customer WHERE sum > 150; -- 9) VIEW에 WHERE문을 단 것 역시, VIEW로 만들 수 있다. CREATE VIEW awesome_customer AS SELECT * FROM total_revenue_per_customer WHERE sum > 150; SELECT * FROM awesome_customer; -- 10) VIEW를 table로 취급하여, ORDER BY 한 것도 가능하다. SELECT * FROM total_revenue_per_customer WHERE sum > 100 ORDER BY sum DESC; -- INSERT INTO VIEW를 통해 VIEW에 값 대입하기는 group by 절이 포함된 VIEW는 사용하지 못한다. -- 위에서 만든 total_revenue_per_customer 같은 것들은 INSERT INTO에 view를 사용하지 못한다. -- 1) group by가 없는 VIEW를 만들자. CREATE VIEW expensive_items AS SELECT * FROM items WHERE price > 100; SELECT * FROM expensive_items -- 2) 여기에 row를 대입해보자. ( 만약, SEQUENCE를 사용한 테이블이라면 해당값 입력x) -- VIEW를 만든 테이블(items)에 값이 자동으로 삽입된다! -- 만약 일부칼럼만 가져온 VIEW라면?;; INSERT INTO expensive_items(id, name, price) VALUES (9, 'DSLR',400.00); SELECT * FROM expensive_items SELECT * FROM items; -- items테이블에도 추가되어있다. -- 3) 만약, VIEW에 포함된 WHERE 조건절을 만족하지 않는 값을 추가한다면? -- VIEW의 WHERE에는 100달러 이상 아이템만 가져오도록했는데, 5달러짜리를 추가해보자. INSERT INTO expensive_items(id, name, price) VALUES (10, 'DSLR', 5.00); SELECT * FROM expensive_items; --결과적으로, items테이블에는 추가되지만, VIEW에서는 안보이게 된다. 왜냐 살아있는 쿼리문이 저장되어있는 테이블이므로 SELECT * FROM items; -- 4) 그렇다면, INSERT INTO VIEW 를 이용해서, VIEW에 달린 WHERE 조건을 만족하는 값만 입력되도록 하려면? -- PostgreSQL에만 있는 코드인 WITH LOCAL CHECK OPTION을 VIEW에 추가해줘야한다. -- WITH LOCAL CHECK OPTION은 데이터를 insert나 update시 where조건절을 항상 체크한다. DROP VIEW IF EXISTS expensive_items; CREATE VIEW expensive_items AS SELECT * FROM items WHERE price > 100 WITH LOCAL CHECK OPTION ; INSERT INTO expensive_items(id, name, price) VALUES (11, 'low camera', 5.00); -- view의 조건을 위반했다고 뜬다. INSERT INTO expensive_items(id, name, price) VALUES (11, 'low camera', 101.00); -- 5) 이번에는 WITH LOCAL CHECK OPTION 없이 만든 expensive_view(100달러이상)에 -- FROM expensive_view + WITH LOCAL CHECK OPTION 으로 -- 10000달러는 이하인 non_luxury_items VIEW를 DROP VIEW IF EXISTS expensive_items; CREATE VIEW expensive_items AS SELECT * FROM items WHERE price >= 100; CREATE VIEW non_luxury_items AS SELECT * FROM expensive_items WHERE price < 10000 WITH LOCAL CHECK OPTION; -- 6) non_luxury_items VIEW 에다가 2달러짜리를 INSERT INTO 를 해보자. -- LOCAL CHECK OPTION은 현재하고 있는 WHERE에 대해서만 체크를 한다고한다. INSERT INTO non_luxury_items(id, name, price) VALUES (12, 'Pencil', 2.00); -- 결과적으로 2달러도 입력이 된다. -- 직접적으로 달리지 않은 expensive_items에 대한 체크를 하지 않는다. -- 즉, non_luxury_items에 대한 check만 시행한다. -- 7) LOCAL 이 아니라 종속관계까지 다 체크해주는 CASCADED CHECK 를 맨 마지막 VIEW에 달면, -- 내부의 VIEW(테이블)의 WHERE절까지 체크해준다. DROP VIEW IF EXISTS non_luxury_items; CREATE VIEW non_luxury_items AS SELECT * FROM expensive_items WHERE price < 10000 WITH CASCADED CHECK OPTION; INSERT INTO non_luxury_items(id, name, price) VALUES (13, 'PencilTwo', 90.00); -- 내부에 있는 VIEW인 expensive_item에 대한 WHERE절에 위반되고 있다고 경고창이 뜬다.
'한의대 생활 > └ PostgreSQL' 카테고리의 다른 글
DATE - timestamp (0) | 2019.01.31 |
---|---|
HAVING* ( group by 결과물의 조건문 ) (0) | 2019.01.30 |
SEQUENCE* ( autoincrement대체 ) and INDEX* ( WHERE서치를 문자열에서 빠르게 내부binary파일생성) (0) | 2019.01.30 |
CREAT TABLE*(primary key, references) and INSERT INTO (0) | 2019.01.29 |
JOIN*(3개 테이블) and GROUP BY*(보이지않더라도 key칼럼으로) and ORDER BY (0) | 2019.01.29 |