분류 전체보기

총정리

SEQUENCE 정리
  1. SEQUENCE 만들기 : CREATE SEQUENCE 시퀀스명 (START n); 
  2. 해당테이블의 해당칼럼 default값을 SEQUENCE로 하나씩 꺼내기 : ALTER TABLE + ALTER COLUMN + SET DEFAULT nextval('시퀀스명');
  3. SEQUENCE를 해당테이블.해당칼럼에 종속시켜 같이 사라지게 하기 : ALTER SEQUENCE 시퀀스명 OWNED BY 테이블명.칼럼명;
  4. 이제 INSERT INTO 테이블시 SEQUENCE칼럼빼고 값 입력하기



INDEX 정리

  1. INDEX는 만들기 : CREATE INDEX 인덱스명 ON 테이블명(칼럼명);
  2. 자주 검색조건에 들어가는 문자열을 WHERE로 서치해도 속도가 빨라진다. 내부 binary tree파일 생성

 

SEQUENCE

-- PostgreSQL에서는 autoincrement가 없다. 대신 우리는 SEQUENCE를 생성해야한다.
SELECT * FROM users;

-- users테이블의 (id, name)에서 id는 자동으로 증가하고 name만 넣어도 되도록 해보자.
-- 1) 일단은 name만 입력시키는 것은 안된다.( id가 primary key로 not null인데 null이 들어갔다고 나옴)
INSERT INTO public.users(name)
VALUES ('chojaeseong')

-- 2) 먼저, SEQUENCE 생성하기 [  CREATE SEQUENCE table명_적용할칼럼명_seq ]
--    우리는 이미 3명이 차있기 때문에, default로 SEQUENCE 생성시 1로 시작해서 오류가 날것이다.
--    [  CREATE SEQUENCE table명_적용할칼럼명_seq  START 4; ]로 시작번호도 알려주자.
CREATE SEQUENCE users_id_seq START 4;


-- 3) ALTER TABLE로 users테이블의 id칼럼의 default value를 SEQUENCE로 SET해주기 
--    만약, SET DEFAULT 9 으로 주면,, 칼럼의 모든 값이 9가 되어버린다.
--    9가 아니라 nextval(' seq name ')이라는 pgSQL의 함수로 SEQUENCE에서 하나씩 꺼내어 대입하는 방식이다.
ALTER TABLE public.users
ALTER COLUMN id
SET DEFAULT nextval('users_id_seq');


SELECT * FROM users;

-- 4) 이제 SEQUENCE를 해당 칼럼에 종속시켜 다른데서 안쓰이고, 지울때 같이 지워지도록 설정해준다.
ALTER SEQUENCE users_id_seq OWNED BY public.users.id;


-- 5) SEQUENCE가 적용된 users테이블의 id값을 주지말고, 다시 name만 입력해보자.
--    id칼럼에 autoincrement같은 SEQUENCE가 적용되면, 빼고 INSERT 해줘도 자동으로 증가한다.
INSERT INTO public.users(name)
VALUES ('chojaeseong')

SELECT * FROM users;

INDEX

-- INDEX 
-- 인덱스는 WHERE 서치를 빠르게 해주는데 유용하다.
SELECT * FROM public.users;

-- 1) 먼저, id가 아닌 name으로 사람의 검색해보고 걸리는 시간을 우측하단에서 확인해보자.
--    만약 데이터가 엄청 많다면, 많은 시간이 걸릴 것이다. 왜냐하면 normal column이기 때문!
SELECT * FROM public.users WHERE name = 'chojaeseong'; -- 12~15msec

-- 2) 인덱스는 자주검색하는 문자열(name 등)에 내부적으로 orderd된 index를 주어 직접 문자열 검색안하고도 빠르게 서치가 가능하게 한다.
--    하지만, 인덱스는 공짜가 아니라서, binary tree를 디스크에 저장해야한다.
--    그러므로, 서칭용 칼럼이 아니여서 INSERT나 UPDATE하는 칼럼에는 적용시키면, 느려진다.
--    즉, 자주 검색하는 칼럼에 index를 지정해주고 내부적으로는 파일이 생성될 뿐.
--     primary key는 특별한 종류의 index이다. 하지만, id로 검색하진 않는다.
--    검색을 자주하는 name칼럼을 인덱스로 지정해보자.
--      [CREATE INDEX 인덱스명(테이블명_칼럼명_index) ON 테이블명(칼럼명);]
CREATE INDEX users_name_index ON public.users(name);

-- 3) 다시 한번 name으로 사람을 검색해보고 시간을 측정해보자.
SELECT * FROM public.users WHERE name = 'chojaeseong'; -- 11 msec까지 나온다.


-- 4) 만약, 2개의 칼럼을 동시에 필터링 하는 작업을 자주한다면, 멀티칼럼 인덱스를 생성할 수 있다.
--     마지막 ON 테이블명(칼럼1, 칼럼2) 형식으로 지정해주면 된다. 그러나 필수는 아니다.
-- 예시)    CREATE INDEX index_name On pulbic.movies(id, user_id) 

-- 5) 다양한 UPDATE로 인해서, index가 꼬였다면, REINDEX TABLE 인덱스명;을 통해 해준다.


R 마크다운 팁 + 단축키

2019. 1. 30. 09:22
  1. html로 Knit 할 때 옵션이 항상 헤깔렸는데 Chunk Output in Console을 선택해야지, 현재 Rmd에 결과안뜨지만 Knit시 결과가 잘나오는 것을 확인

  2. chunk 생성 : Ctrl + Alt + I

  3. knit 단축키 : Ctrl + Shift + K

  4. 주석 : ctrl+shift+/ (내가 설정함)

  5. 구역나누기 주석 : Ctrl + shift + R


01. 29 식권 대량구매

2019. 1. 30. 09:13

매일 혜화역에서 밥을 사먹어야하다보니
여자친구 부모님이 보내주신 반찬도 다 먹어서
승*선생님의 도움을 받아 서울대병원 식권을 대량구매했다
35장 * 장당 4000원 = 14만원 정듀

한달정도는 식비랑 시간을 아낄 수 있겠다.

필요할때 많이들 도와주셔서 너무감사하다!

R markdown

데이터 가져오기

setwd("C:/Users/is2js/python_da/deep analysis(논문용 설문지 분석)")
table = read.csv('sens_spec_for_r_table.csv', header = T)
head(table)
##   Kind.of.medicinal.herbs Sensitivity Specitivity              Group
## 1                      SA        0.95       1.000 Ph.D. of Herbology
## 2                      SA        0.95       1.000 Ph.D. of Herbology
## 3                      SA        1.00       0.875 Ph.D. of Herbology
## 4                      SA        0.95       0.900 Ph.D. of Herbology
## 5                      SA        0.90       1.000 Ph.D. of Herbology
## 6                      SA        0.95       0.800 Ph.D. of Herbology

dplyr - filter + 사용자 정의 함수로 약재별로 나누기

library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
herb <- function(table, herbname){
  a = filter(table, Kind.of.medicinal.herbs == herbname)
  return(a)
  
}

ac = herb(table,"AC")
amc = herb(table, "AMC")
sa = herb(table, "SA")

Kruskal-Wallis Test

  • 각 약재별로 kruskal.test(민감도칼럼 ~ 그룹칼럼)
  • Kruskal-Wallis test(비모수적 검정)을 사용해야한다. =>
  • H0 : 3그룹의 차이가 없다.
# n수가 적어 정규분포 안따르는 비모수검정 -> 3 그룹간의 차이를 검정
# (정규분포를 따르지 않는)AC에 대한 3그룹 민감도 차이가 없다(H0)를 검정
kruskal.test(ac$Sensitivity ~ ac$Group)  #p-value = 0.02285
## 
##  Kruskal-Wallis rank sum test
## 
## data:  ac$Sensitivity by ac$Group
## Kruskal-Wallis chi-squared = 7.5576, df = 2, p-value = 0.02285
kruskal.test(amc$Sensitivity ~ amc$Group)  #p-value = 0.3188
## 
##  Kruskal-Wallis rank sum test
## 
## data:  amc$Sensitivity by amc$Group
## Kruskal-Wallis chi-squared = 2.2864, df = 2, p-value = 0.3188
kruskal.test(sa$Sensitivity ~ sa$Group)  #p-value = 0.3099
## 
##  Kruskal-Wallis rank sum test
## 
## data:  sa$Sensitivity by sa$Group
## Kruskal-Wallis chi-squared = 2.3433, df = 2, p-value = 0.3099

사후검정 - 각 2군씩로 Mann-Whitney test by bonferroni’s method

  • “pgirmess” 패키지 - kruskalmc( 민감도칼럼, 그룹칼럼)
  • bonferroni’s method란 기존 유의수준(5%)에 nC2 = 2군씩 검정횟수를 나누어 유의수준을 낮추는 것
#install.packages("pgirmess")
library(pgirmess)

kruskalmc(ac$Sensitivity,ac$Group)
## Multiple comparison test after Kruskal-Wallis 
## p.value: 0.05 
## Comparisons
##                                    obs.dif critical.dif difference
## KMD-Ph.D. of Herbology            44.75000     44.74725       TRUE
## KMD-Undergraduates                 2.22973     27.19549      FALSE
## Ph.D. of Herbology-Undergraduates 42.52027     37.51044       TRUE
kruskalmc(amc$Sensitivity,amc$Group)
## Multiple comparison test after Kruskal-Wallis 
## p.value: 0.05 
## Comparisons
##                                      obs.dif critical.dif difference
## KMD-Ph.D. of Herbology            23.7916667     44.74725      FALSE
## KMD-Undergraduates                 0.4087838     27.19549      FALSE
## Ph.D. of Herbology-Undergraduates 23.3828829     37.51044      FALSE
kruskalmc(sa$Sensitivity,sa$Group)
## Multiple comparison test after Kruskal-Wallis 
## p.value: 0.05 
## Comparisons
##                                     obs.dif critical.dif difference
## KMD-Ph.D. of Herbology            26.875000     44.74725      FALSE
## KMD-Undergraduates                 4.600225     27.19549      FALSE
## Ph.D. of Herbology-Undergraduates 22.274775     37.51044      FALSE

정리해보기

  • pgSQL에서는 테이블생성시 public. 등의 스키마를 테이블명 앞에 붙힌다( 생략시 default - public. 자동)

  • 2번째 테이블 생성부터는, 자신이 필요한 id(PRIMARY KEY)와 칼럼을 입력후 -> 참조 테이블을 고려한다.

    1) 참조테이블_id(칼럼명)  +  참조테이블의 PRIMARY KEY와 같은 datatype REFERENCES  스키마.참조테이블명 
    2) 이렇게 지정해주면 참조테이블의 PRIMARY KEY는 2번째 테이블의 FOREIGN KEY가 되어버린다

  • 1번째 테이블을 먼저 입력한 뒤, 참조테이블인 2번째 테이블에 데이터 입력한다.

    1) 이 때, 1번째 테이블의 PRIMARY KEY = 2번째 테이블의 FOREIGN KEY에 없는 값은 입력되지 않는다.



CREATE TABLE

-- CREATE TABLE --
-- 만약 default schema인 public을 사용할 것이라면, public.은 생략해도 된다.

-- users테이블을 맨 처음 만들기.
CREATE TABLE public.users (
id integer PRIMARY KEY,  --사용자가 많다면 *bigint를 사용하면 된다. datatype다음에 PRIMARY KEY를 지정해주면 된다.
name character varying(100) NOT NULL, --*pgSQL에서는 varchar(255)가 아니라 character varying(255)로 사용한다.
)


-- PRIMARY KEY 지정은, 다 칼럼들 작성하고 난 다음에, CONSTRAINT로 지정해줄 수 있다.
-- CONSTRAINT + constraint's name + PRIMARY KEY + (칼럼명) 
-- ()안에는 여러개의 primary key를 지정해 줄 수 도 있다.
CREATE TABLE public.users (
id integer,
name character varying(100) NOT NULL, 
CONSTRAINT users_id_pkey PRIMARY KEY (id)
)


-- 그러나 *** 추천 ***은 칼럼 만들때 지정해주는 것이다.
CREATE TABLE public.users (
id integer PRIMARY KEY, 
name character varying(100) NOT NULL
)

SELECT * FROM users





-- videos 테이블 만들기
-- 1) videos에 필요한 칼럼들 먼저 넣기
CREATE TABLE public.videos (
id integer PRIMARY KEY,
name character varying(255) NOT NULL
)

-- 2) *** users 테이블과 연관관계를 고려하여, 어떤사람이 업로드 했는지 id가 필요함.
--    *** id와 users_id가 상관관계가 있으니 라인을 비슷한데 두자.
--     (1) user_id는 users 테이블과 같은 datatype을 가져야할 것이다.
CREATE TABLE public.videos (
id integer PRIMARY KEY,
user_id integer,
name character varying(255) NOT NULL
)
--     (2) user_id는 users 테이블의 id만 들어갈 수 있어야한다.******
--          users 테이블을 참조값만 들어가는 테이블임을 < REFRENCES 스키마.테이블 >로 명시해준다.
--        REFERENCES만 정해주면, ***참조테이블의 primay key가 자동적으로 체크된다.
CREATE TABLE public.videos (
id integer PRIMARY KEY,
user_id integer REFERENCES public.users,
name character varying(255) NOT NULL
)

SELECT * FROM videos

INSERT INTO

-- INSERT INTO --
-- 1) user table에 넣기 *** video 테이블은 users 테이블을 참조하고 있기 때문에 값을 바로 넣을 수 없다 ****
--    테이블명다음에 블라켓()에 칼럼리스트를 적어줘도 되지만, 생략해도 된다.
INSERT INTO public.users(id,name)
VALUES (1, 'marysmith');

SELECT * FROM public.users


INSERT INTO public.users
VALUES (2, 'rolfsmith');

SELECT * FROM public.users

INSERT INTO public.users
VALUES (3, 'josesalvatierra');


-- 2) videos 테이블은, user_id칼럼이 users테이블의 primaykey를 참조하고 있기 때문에,
--     uses테이블을 먼저 채워넣고 ----> 거기에 있는 값만 INSERT INTO 할 수 있다.
--    참조하는 순간 uses테이블의 primary key는 **자동으로 videos테이블의 foreign key가 된다.***
SELECT * FROM public.videos;

--    (1) 만약 users테이블에 없는 값을 입력시킨다면, 에러가 난다.
INSERT INTO public.videos
VALUES (1, 10, 'Test Video');

--     (2) users 테이블의 primary key = videos테이블이 참조해서  foreign key가 된다.
INSERT INTO public.videos
VALUES (1, 2, 'Test Video');

SELECT * FROM public.videos;




-- 3) 이제 2개 테이블을 조인시켜보자.
SELECT * FROM public.videos
INNER JOIN public.users ON public.users.id = public.videos.user_id;




-- 4) users테이블에서 primary key(***자동적으로 NOT NULL적용***)을 
--     autoincrementing 로 적용시켜서 -> name만 입력하면 id가 자동으로 올라가도록 해보자.


* 정리해보기

  • JOIN한 상태에서 ~별  ~집계를 할때, 기준테이블의 id로 GROUP BY 하되, 기준테이블의 칼럼들은 SELECT할 수 있으나, 집계시에도 COUNT()는 집계테이블의 id로 COUNT()하되, 집계되는 테이블은 1 row로 접혀서 숫자계산되기 때문에 SELECT문에 칼럼명을 못넣는다.
  • 만약, 집계테이블의 칼럼을 groupby의 기준에 넣는다면, 집계테이블 칼럼을 SELECT할 수 있다. 그러나 기준테이블은 안해두 가능!!


JOIN 3개 테이블 해보기

SELECT * FROM purchases;

SELECT * FROM items;

SELECT * FROM customers;


-- 1) item들 중에  구매한 items 목록을 원하는 경우
SELECT * FROM items
JOIN purchases ON items.id = purchases.id;


-- left조인을 쓴다면, 구매하지 않은 아이템도 블랭크로 붙는다.
SELECT * FROM items
LEFT JOIN purchases ON items.id = purchases.id;


-- 2) 이제 어느 고객이 어느 아이템을 샀는지 join해보자.
SELECT * FROM customers
JOIN purchases ON customers.id = purchases.customer_id;

--left join
SELECT * FROM customers
LEFT JOIN purchases ON customers.id = purchases.customer_id;

-- 고객 중에 구매를 한 고객 join데이터 중 이름만 select하기
SELECT customers.first_name, customers.last_name FROM customers
JOIN purchases ON customers.id = purchases.customer_id;



-- 3) ***3개 테이블 한꺼번에 join해보기***
---- (1) items중에 구매한 것들만 item만 나오도록 inner join한다.
SELECT * FROM items
INNER JOIN purchases ON items.id = purchases.item_id

---- (2) 여기서 보이는 customer_id로 고객들을 연결할 수 있을 것이다. *** JOIN한것에 바로 JOIN을 해버린다.
SELECT * FROM items
INNER JOIN purchases ON items.id = purchases.item_id
INNER JOIN customers ON purchases.customer_id = customers.id


---- (3) 필요한 칼럼만 챙겨보자.
SELECT customers.first_name, customers.last_name, items.name, items.price FROM items
INNER JOIN purchases ON items.id = purchases.item_id
INNER JOIN customers ON purchases.customer_id = customers.id



GROUP BY

-- GROUP BY --
-- JOIN의 결과는 duplicated된 row들로 나열되서 나타나니 GROUP BY <사람테이블의 id>를 활용해야한다.

SELECT * FROM customers;

-- ***left join***의 결과 ***모든*** 고객들 중에, 구매한 고객들 + 구매안한 고객들의 정보들이 다 나온다
-- left join을 하는 이유는 group by 로 count할 때, *** 구매안한사람도 0으로 count하기위해 ***
-- 하지만, 나는 구매info(item_id) + 연결키(customer_id)가 중요한게 아니라, 얼마나 많이 구매했는지 알고 싶은 상황이다.
-- 각 구매info가 따로따로 row로 나뉘어서 나오므로 이 때 필요한 것이 groupby이다.
SELECT * FROM customers
LEFT JOIN purchases ON customers.id = purchases.customer_id;


-- 1) 이름정보와, purchases테이블에서는 ***primary key인 id만 가져온다. for COUNT ***
--    하지만, 여기까지도 row가 나뉘어져있다.
SELECT customers.first_name, customers.last_name, purchases.id FROM customers
LEFT JOIN purchases ON customers.id = purchases.customer_id;

-- 2) 이제 count하고 싶은 칼럼인 puchases의 primary key id칼럼에 count함수를 넣어준다.
--    이대로는 에러가 난다. 그래서 필요한 것이 GROUP BY 이다.
--    *** 이때, 보이지 않더라도 LEFT테이블인 customers의 identity & primary key인 id칼럼으로 groupby 한다***
SELECT customers.first_name, customers.last_name, COUNT(purchases.id) FROM customers
LEFT JOIN purchases ON customers.id = purchases.customer_id
GROUP BY customers.id;




-- 3) ***SUM() - GROUP BY를 이용하여, 
--    아이템들 중 구매된 아이템만* 골라내는 INNER JOIN을 한 뒤, 
--     구매된 아이템 중 고객들customers들을 다시 INNER JOIN시켜붙혀보자.
SELECT * FROM items;

SELECT * FROM items 
INNER JOIN purchases ON items.id = purchases.item_id;

SELECT * FROM items 
INNER JOIN purchases ON items.id = purchases.item_id
INNER JOIN customers ON purchases.customer_id = customers.id;

-- 4) 여기에 *** 고객별 의 id로 groupby -> 집계함수 SUM()*** 시켜보자.
--    만약 GROUP BY 만 쓸때, *로 모든 칼럼들에 접근한 상태라면, 데이터 접근 중이므로 GROUP BY로 합칠 수가 없다.
--      필요칼럼선택(GROUP BY 기준 테이블안의) + (GROUP BY기준아닌 테이블의 칼럼을 합칠)집계함수를 사용해야한다.
--    my) customers의 id로 GROUP BY를 한다면, customers테이블은 칼럼 정보 살아 있어서 가져올 수 있다.
-- *********GROUP BY기준이 아닌 테이블의 칼럼들은 개별접근x COUNT(), SUM() 등으로 접혀들어가야한다.
SELECT * FROM items 
INNER JOIN purchases ON items.id = purchases.item_id
INNER JOIN customers ON purchases.customer_id = customers.id
GROUP BY customers.id;

SELECT customers.first_name, customers.last_name, SUM(items.price) FROM items 
INNER JOIN purchases ON items.id = purchases.item_id
INNER JOIN customers ON purchases.customer_id = customers.id
GROUP BY customers.id;

-- 5) 숙제 = 모든 고객이 구매한 가격의 합 ( customers 테이블 연결없이 해봤다 )
--    GROUP BY 의 기준을 items.id로 잡았다면 items테이블 칼럼은 접근가능 -> purchases테이블은 접히니까, 집계함수
SELECT items.name, SUM(items.price) FROM items 
INNER JOIN purchases ON items.id = purchases.item_id
GROUP BY items.id;

SELECT SUM(items.price) FROM items 
INNER JOIN purchases ON items.id = purchases.item_id

-- 5-정답)
-- 1) 전체 고객들이 얼마나 많은 돈을 소비했는지 알아보기

--     (1) 구매 정보 테이블 가져오기
SELECT * FROM purchases;

--    (2) 구매정보에 items정보 붙히기 innerjoin    
SELECT * FROM purchases
INNER JOIN items ON purchases.item_id = items.id;

--     (3) SUM()만 해주기
SELECT SUM(items.price) FROM purchases
INNER JOIN items ON purchases.item_id = items.id;

ORDER BY

-- Order by --

-- 이전에 했던대로, *각각의 고객들이 얼마나 많은 *돈을 소비했는지 다시 찾아보자
-- 1) 3개 테이블 다 조인하기 
SELECT * FROM items
INNER JOIN purchases ON purchases.item_id = items.id
INNER JOIN customers ON purchases.customer_id = customers.id;

-- 2) 필요칼럼 셀렉트하기
SELECT customers.first_name, customers.last_name, items.price FROM items
INNER JOIN purchases ON purchases.item_id = items.id
INNER JOIN customers ON purchases.customer_id = customers.id;

-- 3) 보이진 않지만, 고객의 primary key인 id칼럼으로 groupby -> SUM()하기
SELECT customers.first_name, customers.last_name, SUM(items.price) FROM items
INNER JOIN purchases ON purchases.item_id = items.id
INNER JOIN customers ON purchases.customer_id = customers.id
GROUP BY customers.id;

-- 4) price순으로 정렬하기 ( alis " 띄워쓰기alias시 따옴표 필수 "  -> ORDER BY에 alias적어주기)
SELECT customers.first_name, customers.last_name, SUM(items.price) AS "total_spent" FROM items
INNER JOIN purchases ON purchases.item_id = items.id
INNER JOIN customers ON purchases.customer_id = customers.id
GROUP BY customers.id
ORDER BY "total_spent";

SELECT customers.first_name, customers.last_name, SUM(items.price) AS "total_spent" FROM items
INNER JOIN purchases ON purchases.item_id = items.id
INNER JOIN customers ON purchases.customer_id = customers.id
GROUP BY customers.id
ORDER BY "total_spent" DESC;

-- 5) TOP 1만 표시해주기
SELECT customers.first_name, customers.last_name, SUM(items.price) AS "total_spent" FROM items
INNER JOIN purchases ON purchases.item_id = items.id
INNER JOIN customers ON purchases.customer_id = customers.id
GROUP BY customers.id
ORDER BY "total_spent" DESC
LIMIT 1;


알아두어야 할 개념

  1. SELECT '문자열' AS 칼럼명으로 새로운 칼럼을 생성할 수 있다.
  2. UNION은 2개의 쿼리문의 칼럼의 갯수/이름이 모두 같을 때 합칠 수 있다.
  3. 전체범주명을 깔고, 특정 범주명을 UNION하는 것은 안되는 것 같다. CASE WHEN 처럼 범주를 다 나눈 다음 UNIO해주는 방법밖에 없나??
  4. UNION은 합집합, UNION ALL은 합집합+교집합 포함

코드

SELECT '5~10만' AS TYPE, * FROM person WHERE personid BETWEEN 50000 AND 100000
UNION 
SELECT '기본 범주' AS TYPE, * FROM person WHERE personid < 50000 OR personid > 100000
ORDER BY personid

csv파일로 보내기

mssql 쿼리문 결과에서 우클릭하기

A : 현재 셀의 위에 새로운 셀을 추가한다.
B : 현재 셀 밑에 새로운 셀을 추가한다.
M : 현재 셀을 markdown 모드로 변경한다.
Y : markdown 모드를 다시 code 모드로 변경한다.
D+D : 현재 셀을 삭제한다.
Enter : command 모드에서 edit 모드로 변경한다.
F : 코드를 find and replace 한다.
O : Output 접기
Shift + Tab : 객체의 docstring(documentation)을 출력한다
Shift + M : 을 누르면 선택된 셀들을 merge 한다.

참고 : https://3months.tistory.com/115?category=753896

전처리시 체크사항

  1. 중복확인 : duplicated(df)로 T/F 마스크를 만들어서, 인덱싱자리에 넣는다. => dpylr 라이브러리 사용
  2. 이상치 확인 : 이상치로 평균값이 튄다.
    ex> 오타, 응급상황 후 어설프게 입력

EDA의 방법 2가지

  1. 데이터 형태에 따른 2가지 EDA

    • 범주형(문자형) : 기초통계시 frequency(빈도)가 나옴

      1) 2개 범주 : 남/녀, 성공/실패와 같은 binary / binomial / dichotomous
      2) 3개이상 범주 : 명목형(Nomial)=순서없는 범주 / 순서형(Ordinal) = 순서있는 범주

    • 숫자형 : 기초 통계시 계산에 의해 평균,최소,최대,4분위수
      cf) %/% : 정수나누기 , %% : 나머지, ^ ** : 승수
      1) 연속형 : 키, 온도 등 소수점 표현이 되는 수로서 통계기법 多
      2) 이산형 : 건수, 개수, 등 측정이 아닌 count수

  2. 변수 개수에 따른 3가지 EDA
    1) 단 변수분석 :

    • 숫자형 단변수 EDA Missing rate, variation 등 확인 => Box plot(분포-통계확인) or hist(정규분포확인)하는 용도
      ex> is.na(age), sum(is.na(age)), mean(is.na(age)), new_age <- c(na.omit(age)) or na.rm = T
      ex> summary(height), quantile(height, na.rm=T), IQR(height, na.rm=T), var(height, na.rm=T), sd()
      cf) 2Q = median = 50% , 3Q - 1Q = IQR -> 가운데 50%가 퍼진 정도
      cf) Boxplot해석 순서 : median(50%)를 기준으로 3Q, 1Q -> 3Q + 1.5IQR = Upper fence / 1Q-1.5IQR = Lower fence -> 이상치들 보기
      cf) histgram : 구간을 쪼갠뒤 -> 카테고리를만들고 -> 그안에 몇개가 있는지 빈도확인 ( no space bar plot )
      cf) 아웃라이어는 평균을 튀게 만드나, 새로운 발견이 필요한 경우 포함시킨다.

    • 범주형 단변수 EDA빈도 or 새로운카테고리 확인->상대빈도 파악후 => 범주별 빈도를 기본으로 그리는 Bar chart => Bar chart에 누적된 line까지 그려주는 파레토 차트
      cf) 범주가 지나치게 많은 경우 => 기타 카테고리로 묶는다.

    2) 이 변수분석 :

    • 범주형 이변수 : 교차표를 위함 => 카이제곱검정으로 2개 이상의 범주형 변수 연관관계 파악 => bar chart with 범주
    • 숫자형 이변수 : 산점도(scatter plot) => 상관관계correlation확인
      cf) 상관관계선형성에 의한 척도이므로 0.7은 없다. 선의 기울기가 30도라도 +1이다. -30도라도 -1이다. 혹은 0으로 선형성이 없다
      cf) 상관계수분포에 대한 것으로 심리분야 0.3이상, 보통 0.7이상이 strong으로 판단, but 그래프 + 수치를 같이 제시해야한다.

    3). 다 변수분석 : 키 + 몸무게 + 혈액형


총 정리

# install.packages("moonBook")
library(moonBook) # ***
data(acs) # ***

getwd()

setwd('C:/Users/is2js/')

# a = read.table('txt_data.txt', header = T) # txt파일 첫줄이 header일시 옵션 넣어주기 ***

# df = read.csv('C:/Users/is2js/R_da/R_Camp/data/week1/csv_data.csv', stringsAsFactors = FALSE) #***

# 윈도우파일 -> 맥에서 여는 인코딩 문제시, fileEncoding = "CP949", encoding = "UTF-8"

dim(acs)
head(acs)
str(acs)
summary(acs)
apply(is.na(acs), MARGIN = 2, FUN = 'sum')

#install.packages("mlr")

library(mlr)
summarizeColumns(iris)

mytable(sex ~ age, data=acs)
mytable(sex ~ BMI, data=acs)
mytable(obesity ~ age+BMI+smoking , data = acs)
mytable(obesity + sex ~ age+BMI+smoking+height , data = acs)

csv <- mytable(obesity + sex ~ age+BMI+smoking+height , data = acs)
mycsv(csv, file = 'obesity and sex.csv')

latex <- mytable(obesity ~ age+BMI+smoking , data = acs)
mylatex(latex)

기술 통계

Numerically - 기초 통계량

a <- c(1, 2, 3, 10)

mean(a) # 중심척도 평균
sd(a) # spread 척도 표준편차

min(a)
max(a)

summary(a) # 한번에 기초 통계 다보기***

boxplot(a)

boxplot(a, horizontal = TRUE) # 박스플롯 가로로 세우기***

데이터 경로 맞춰주기***

워킹 디렉토리 확인***
폴더경로를 복사해왔으면 항상 /로 변환해줘야한다. in Windows

getwd()
## [1] "C:/Users/is2js/R_da/myR"
setwd('C:/Users/is2js/R_da/R_Camp/data/week1')

a = read.table('txt_data.txt', header = T) # txt파일 첫줄이 header일시 옵션 넣어주기 ***

데이터 확인하기 ***

  1. dim() : 행(observation), 열(variable) 개수 확인
  2. head() : 직접 요약 보기
  3. str() : 데이터 구조 및 타입 보기
  4. summary() : 기초통계량과 범주형의 frequency 확인하기
  5. apply() : na를 apply+2+sum으로 칼럼별 개수 확인하기
dim(a) # ***
## [1] 10  3
head(a) 
##   age gender group
## 1  25      M     a
## 2  30      M     a
## 3  30      F     a
## 4  25      F     a
## 5  30      M     b
## 6  40      F     b
str(a) 
## 'data.frame':    10 obs. of  3 variables:
##  $ age   : int  25 30 30 25 30 40 35 50 40 45
##  $ gender: Factor w/ 2 levels "F","M": 2 2 1 1 2 1 2 1 2 2
##  $ group : Factor w/ 2 levels "a","b": 1 1 1 1 2 2 2 1 1 2
summary(a) 
##       age       gender group
##  Min.   :25.0   F:4    a:6  
##  1st Qu.:30.0   M:6    b:4  
##  Median :32.5               
##  Mean   :35.0               
##  3rd Qu.:40.0               
##  Max.   :50.0
apply(is.na(a), MARGIN = 2, FUN = 'sum') # ***
##    age gender  group 
##      0      0      0

csv파일 + 문자형을 Factor전환 방지 ***

stringAsFactors = FALSE 대신, summary시 범주형 칼럼의 빈도가 안나타난다..

df = read.csv('C:/Users/is2js/R_da/R_Camp/data/week1/csv_data.csv', stringsAsFactors = FALSE) #***

dim(df) # ***

## [1] 1003   17
head(df) 
##   id gender age height weight cancer cancer_onset HP diabetes 혈당1 혈당2
## 1  1      M  22    184     79      N               N        N    89   118
## 2  2      M  70    185     67      N               N        N   116   120
## 3  3      F  32    179     75      N               Y        Y   104    88
## 4  3      F  32    179     75      N               Y        Y   104    88
## 5  4      F  29    166     45      Y   2016-01-25  N        N    88   115
## 6  5      F  53    164     50      Y   2016-04-29  N        N   106    98
##   혈당3 body_temp spo2 맥박 sbp dbp
## 1   129        39   39   94 123  84
## 2   130        35   36  102 131  88
## 3   124        36   37   83 103  64
## 4   124        36   37   83 103  64
## 5    87        39   35   73 101  85
## 6    83        39   37   74 121  61
str(df) 
## 'data.frame':    1003 obs. of  17 variables:
##  $ id          : int  1 2 3 3 4 5 6 7 8 9 ...
##  $ gender      : chr  "M" "M" "F" "F" ...
##  $ age         : int  22 70 32 32 29 53 63 50 57 35 ...
##  $ height      : int  184 185 179 179 166 164 166 165 181 185 ...
##  $ weight      : int  79 67 75 75 45 50 97 53 66 67 ...
##  $ cancer      : chr  "N" "N" "N" "N" ...
##  $ cancer_onset: chr  "" "" "" "" ...
##  $ HP          : chr  "N" "N" "Y" "Y" ...
##  $ diabetes    : chr  "N" "N" "Y" "Y" ...
##  $ 혈당1       : int  89 116 104 104 88 106 99 98 90 99 ...
##  $ 혈당2       : int  118 120 88 88 115 98 127 99 96 83 ...
##  $ 혈당3       : int  129 130 124 124 87 83 133 101 109 81 ...
##  $ body_temp   : int  39 35 36 36 39 39 38 37 39 35 ...
##  $ spo2        : int  39 36 37 37 35 37 37 37 39 38 ...
##  $ 맥박        : int  94 102 83 83 73 74 75 93 110 85 ...
##  $ sbp         : int  123 131 103 103 101 121 130 131 109 117 ...
##  $ dbp         : int  84 88 64 64 85 61 98 76 88 74 ...
summary(df) 
##        id            gender               age             height     
##  Min.   :   1.0   Length:1003        Min.   :-25.00   Min.   :160.0  
##  1st Qu.: 250.5   Class :character   1st Qu.: 35.00   1st Qu.:168.0  
##  Median : 501.0   Mode  :character   Median : 50.00   Median :174.0  
##  Mean   : 501.0                      Mean   : 49.72   Mean   :173.8  
##  3rd Qu.: 751.5                      3rd Qu.: 65.00   3rd Qu.:181.0  
##  Max.   :1000.0                      Max.   : 80.00   Max.   :187.0  
##                                                       NA's   :2      
##      weight          cancer          cancer_onset            HP           
##  Min.   : 40.00   Length:1003        Length:1003        Length:1003       
##  1st Qu.: 56.00   Class :character   Class :character   Class :character  
##  Median : 71.00   Mode  :character   Mode  :character   Mode  :character  
##  Mean   : 70.99                                                           
##  3rd Qu.: 86.00                                                           
##  Max.   :100.00                                                           
##                                                                           
##    diabetes             혈당1            혈당2           혈당3    
##  Length:1003        Min.   : 80.00   Min.   : 80.0   Min.   : 80  
##  Class :character   1st Qu.: 90.00   1st Qu.: 91.0   1st Qu.: 94  
##  Mode  :character   Median : 99.00   Median :104.0   Median :111  
##                     Mean   : 99.79   Mean   :104.5   Mean   :110  
##                     3rd Qu.:110.00   3rd Qu.:117.0   3rd Qu.:125  
##                     Max.   :120.00   Max.   :130.0   Max.   :140  
##                                                                   
##    body_temp           spo2           맥박             sbp       
##  Min.   : 35.00   Min.   :35.0   Min.   : 60.00   Min.   :100.0  
##  1st Qu.: 36.00   1st Qu.:36.0   1st Qu.: 73.00   1st Qu.:110.0  
##  Median : 37.00   Median :37.0   Median : 85.00   Median :120.0  
##  Mean   : 37.49   Mean   :37.5   Mean   : 85.49   Mean   :120.2  
##  3rd Qu.: 39.00   3rd Qu.:39.0   3rd Qu.: 99.00   3rd Qu.:130.0  
##  Max.   :120.00   Max.   :40.0   Max.   :110.00   Max.   :140.0  
##                                                                  
##       dbp        
##  Min.   : 60.00  
##  1st Qu.: 70.00  
##  Median : 80.00  
##  Mean   : 80.06  
##  3rd Qu.: 90.00  
##  Max.   :100.00  
## 
apply(is.na(df), MARGIN = 2, FUN = 'sum') # ***
##           id       gender          age       height       weight 
##            0            0            0            2            0 
##       cancer cancer_onset           HP     diabetes        혈당1 
##            0            0            0            0            0 
##        혈당2        혈당3    body_temp         spo2         맥박 
##            0            0            0            0            0 
##          sbp          dbp 
##            0            0

moonbook 패키지 설치 및 mytable 사용 ***

<열>범주별 ~ <행1, 2, 3> int숫자(기술통계) + 범주(frequency) + , data= mytable() 함수로 제공

# install.packages("moonBook")

library(moonBook) # ***

# require(moonBook)

data(acs) # ***

getwd()

## [1] "C:/Users/is2js/R_da/myR"
setwd('C:/Users/is2js/R_da/R_Camp/data/week1')


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
# 의학논문 Table 1(기술 통계)을 만들어주는 mytable()함수 ***
# 인구 통계학 정보를 Table 1형태로 만들어준다.
# (열(범주)별 ~ 행(숫자or범주)변수1+변수2 +.., data=)

# 1. y : sex(범주)별 ~ age(int)의 기술통계
mytable(sex ~ age, data=acs)
## 
##  Descriptive Statistics by 'sex' 
## __________________________________ 
##        Female       Male       p  
##        (N=287)     (N=570)  
## ---------------------------------- 
##  age 68.7 ± 10.7 60.6 ± 11.2 0.000
## ----------------------------------
# 2. y : sex(범주)별 ~ BMI(int)의 기술통계
mytable(sex ~ BMI, data=acs)
## 
##  Descriptive Statistics by 'sex' 
## __________________________________ 
##        Female       Male       p  
##        (N=287)     (N=570)  
## ---------------------------------- 
##  BMI 24.2 ±  3.6 24.3 ±  3.2 0.611
## ----------------------------------
# 3. y : obesity(범주)별 ~ age(int), BMI(int), smoking(범주)
mytable(obesity ~ age+BMI+smoking , data = acs)
## 
##     Descriptive Statistics by 'obesity'    
## ____________________________________________ 
##                    No          Yes       p  
##                  (N=567)     (N=290)  
## -------------------------------------------- 
##  age           64.7 ± 11.7 60.6 ± 11.3 0.000
##  BMI           22.3 ±  2.0 27.5 ±  2.5 0.000
##  smoking                               0.688
##    - Ex-smoker 130 (22.9%) 74 (25.5%)       
##    - Never     221 (39.0%) 111 (38.3%)      
##    - Smoker    216 (38.1%) 105 (36.2%)      
## --------------------------------------------
# 4. y : obesity(범주) + sex(범주)별 ~ 숫자 + 범주
# - 범주가 2개일 때는, 순서대로 계층을 가지게 보여준다.
mytable(obesity + sex ~ age+BMI+smoking+height , data = acs)
## 
##            Descriptive Statistics stratified by 'obesity' and 'sex'          
## ______________________________________________________________________________ 
##                               Yes                               No               
##                ------------------------------- ------------------------------- 
##                   Female        Male       p      Female        Male       p  
##                   (N=93)      (N=197)           (N=194)      (N=373)        
## ------------------------------------------------------------------------------ 
##  age           66.9 ± 10.4  57.6 ± 10.4  0.000 69.5 ± 10.8  62.2 ± 11.3  0.000
##  BMI           27.7 ±  2.7  27.4 ±  2.3  0.310 22.2 ±  2.1  22.4 ±  1.9  0.281
##  smoking                                 0.000                           0.000
##    - Ex-smoker  16 (17.2%)   58 (29.4%)         33 (17.0%)   97 (26.0%)       
##    - Never      68 (73.1%)   43 (21.8%)        141 (72.7%)   80 (21.4%)       
##    - Smoker     9 ( 9.7%)    96 (48.7%)         20 (10.3%)  196 (52.5%)       
##  height        153.5 ±  6.4 168.1 ±  6.8 0.000 153.9 ±  6.2 167.8 ±  5.7 0.000
## ------------------------------------------------------------------------------

moonBook - mylatex()함수

  • mytable()함수의 결과를 변수에 저장한 뒤, mylatex(변수)로 활용
latex <- mytable(obesity ~ age+BMI+smoking , data = acs)
mylatex(latex)
## \begin{table}[!hbp]
## \begin{normalsize}
## \begin{tabular}{lccc}
## \multicolumn{4}{c}{Descriptive Statistics by obesity}\\ 
## \hline
##  & No & Yes & \multirow{2}{*}{p}\\ 
##  & (N=567) & (N=290) &  \\ 
## \hline
## age           & 64.7 ± 11.7 & 60.6 ± 11.3 & 0.000\\ 
## BMI           & 22.3 ±  2.0 & 27.5 ±  2.5 & 0.000\\ 
## smoking       &  &  & 0.688\\ 
##   - Ex-smoker & 130 (22.9\%) & 74 (25.5\%) & \\ 
##   - Never     & 221 (39.0\%) & 111 (38.3\%) & \\ 
##   - Smoker    & 216 (38.1\%) & 105 (36.2\%) & \\ 
## \hline
## \end{tabular}
## \end{normalsize}
## \end{table}

moonBook - mycsv()함수

  • mytable결과를 변수에 저장한 뒤, mycsv(변수명, file= ‘파일명.csv’)
csv <- mytable(obesity + sex ~ age+BMI+smoking+height , data = acs)
mycsv(csv, file = 'obesity and sex.csv')

mlr 패키지 설치 및 summarizeColumns()

  • str()처럼 컬럼명/type + na 개수 + mean 등 기초 기술통계량 + factorlevel 수 표시
# install.packages("mlr")
library(mlr)
## Loading required package: ParamHelpers
summarizeColumns(iris)
##           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


순서대로

default

Django

RDark

Midnight

Emacs

FadeToGrey

Eclipse

sql파일

엑셀파일


CREATE DATABASE practice_medi2 USE practice_medi2 -- CodeMaster 칼럼2개 제외 DB우클릭 > T, I > END + W + TAb 아래2칸 + ShiftTaB3칸 파일선택 > N > N > END 위로3칸 > N N F -- 가져오기마법사로 실패하는 경우 -- 1. Table 생성 > 2. BELK INSERT 로 csv 파일 집어넣기 create table Person ( personid int, sex int, birthday datetime, ethnicity int ) -- bulk insert Person from 'C:\Users\is2js\Desktop\인턴활동\0111 DB세미나\sql_loading_sample\sample_person.csv' with (firstrow=2, format='CSV') create table Electrocardiogram ( personid int, ecgdate datetime null, RR int null, QT int null, QTc int null, ACCI int null, ecgdept varchar(2) null, ecgsource varchar(2) null, ) bulk insert Electrocardiogram from 'C:\Users\is2js\Desktop\인턴활동\0111 DB세미나\sql_loading_sample\sample_Electrocardiogram.csv' with (firstrow=2, KEEPNULLS, format='CSV') create table Laboratory ( personid int, labdate datetime null, labname varchar(2) null, labvalue float null ) bulk insert Laboratory from 'C:\Users\is2js\Desktop\인턴활동\0111 DB세미나\sql_loading_sample\sample_Laboratory.csv' with (firstrow=2, KEEPNULLS, format='CSV') create table Diagnosis ( personid int, diagdate datetime, diagcode varchar(20), diaglocalcode varchar(20), diagdept varchar(2) ) bulk insert Diagnosis from 'C:\Users\is2js\Desktop\인턴활동\0111 DB세미나\sql_loading_sample\sample_Diagnosis.csv' with (firstrow=2, KEEPNULLS, format='CSV') drop table Drug create table Drug ( personid int, drugdate datetime null, druglocalcode varchar(20), atccode varchar(20), drugdept varchar(2), [route] varchar(2), duration int ) bulk insert Drug from 'C:\Users\is2js\Desktop\인턴활동\0111 DB세미나\sql_loading_sample\sample_Drug.csv' with (firstrow=2, KEEPNULLS, format='CSV') create table DiagnosisCodeMaster ( diaglocalcode varchar(20), diagnosis varchar(max) ) bulk insert DiagnosisCodeMaster from 'C:\Users\is2js\Desktop\인턴활동\0111 DB세미나\sql_loading_sample\DiagnosisCodeMaster.csv' with (firstrow=2, KEEPNULLS, format='CSV') create table DrugCodeMaster ( druglocalcode varchar(20), drugigrdname varchar(100) ) bulk insert DrugCodeMaster from 'C:\Users\is2js\Desktop\인턴활동\0111 DB세미나\sql_loading_sample\DrugCodeMaster.csv' with (firstrow=2, KEEPNULLS, format='CSV') -- 실전 분석해보기 -- -- alt+f1, 엑셀-- [dbo].[person] [dbo].[drug] [dbo].[DrugCodeMaster] [dbo].[Diagnosis] [dbo].[DiagnosisCodeMaster] [dbo].[Electrocardiogram] [dbo].[laboratory] -- 개수 한꺼번에 세기 SELECT COUNT(1) FROM [person] --18570 SELECT COUNT(1) FROM [drug] --1890626 SELECT COUNT(1) FROM [DrugCodeMaster] --2627 SELECT COUNT(1) FROM [Diagnosis] --296690 SELECT COUNT(1) FROM [DiagnosisCodeMaster] --7553 SELECT COUNT(1) FROM [Electrocardiogram] --35932 SELECT COUNT(1) FROM [laboratory] --147716 ---person table 분석 Person --칼럼명 personid sex birthday ethnicity -- 데이터 전체 head보기 SELECT TOP 100 * FROM person -- key 칼럼의 distinct한 개수 보기 -- person SELECT COUNT(DISTINCT personid) FROM person --18570 -- sex SELECT TOP 100 sex FROM person --head SELECT DISTINCT sex FROM person --sex의 종류 : 1, 0 SELECT COUNT(DISTINCT sex) FROM person --sex 종류개수 : 2가지 - 종류가 너무 많을 때 SELECT sex, COUNT(DISTINCTpersonid) cnt FROM person --1 9307 / 0 9263 GROUP BY sex SELECT 9307 + 9263 -- 전체(18570)과 sex의 범주별 합(1+0)이 같은지 보고, sex에서 null없나 확인 SELECT * FROM person -- sex에 null값 확인 WHERE sex IS NULL SELECT sex, COUNT(personid) FROM person GROUP BY sex ORDER BY 1 --birthday SELECT TOP 100 birthday FROM person --head SELECT birthday, COUNT(personid) cnt FROM person --시계열별 groupby count(사람수) GROUP BY birthday SELECT birthday, COUNT(personid) cnt FROM person --시계열별 groupby count(사람수) -> Order by 후 엑셀 시각화 GROUP BY birthday ORDER BY 1 SELECT GETDATE() SELECT DATEDIFF(year, birthday, GETDATE()) FROM person -- 해나이 : interval을 year로 SELECT DATEDIFF(day, birthday, GETDATE()) / 365 FROM person -- 만나이 : interval을 day로 계산한 뒤, 365일을 나눠주기(몫만 남음) SELECT DATEDIFF(year, birthday, GETDATE()) 해나이, DATEDIFF(day, birthday, GETDATE()) / 365 만나이 FROM person SELECT CASE WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 0 and 9 THEN '10세 미만' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 10 and 19 THEN '10대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 20 and 29 THEN '20대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 30 and 39 THEN '30대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 40 and 49 THEN '40대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 50 and 59 THEN '50대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 60 and 69 THEN '60대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 70 and 79 THEN '70대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 80 and 89 THEN '80대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 >= 90 THEN '90세 이상' END AS 연령대, * FROM person -- 변형칼럼을 groupby 하기 위해, SELECT *INTO* FROM으로 새 테이블 만들기 SELECT CASE WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 0 and 9 THEN '10세 미만' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 10 and 19 THEN '10대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 20 and 29 THEN '20대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 30 and 39 THEN '30대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 40 and 49 THEN '40대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 50 and 59 THEN '50대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 60 and 69 THEN '60대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 70 and 79 THEN '70대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 80 and 89 THEN '80대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 >= 90 THEN '90세 이상' END AS 연령대, * INTO person_with_age FROM person SELECT TOP 100 * FROM person_with_age -- 새 테이블로 연령대별 groupby 사람수 카운트하기 SELECT 연령대, COUNT(personid) cnt FROM person_with_age GROUP BY 연령대 ORDER BY 1 --subquery로 테이블 생성없이 하기 SELECT 연령대, COUNT(personid) cnt FROM ( SELECT CASE WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 0 and 9 THEN '10세 미만' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 10 and 19 THEN '10대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 20 and 29 THEN '20대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 30 and 39 THEN '30대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 40 and 49 THEN '40대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 50 and 59 THEN '50대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 60 and 69 THEN '60대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 70 and 79 THEN '70대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 80 and 89 THEN '80대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 >= 90 THEN '90세 이상' END AS 연령대, * FROM person )Z GROUP BY 연령대 ORDER BY 1 -- sex > 연령대 순으로 해야지 엑셀로 시각화 하기 쉬움(나중에 앎) SELECT 연령대, sex, COUNT(personid) cnt FROM ( SELECT CASE WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 0 and 9 THEN '10세 미만' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 10 and 19 THEN '10대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 20 and 29 THEN '20대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 30 and 39 THEN '30대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 40 and 49 THEN '40대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 50 and 59 THEN '50대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 60 and 69 THEN '60대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 70 and 79 THEN '70대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 BETWEEN 80 and 89 THEN '80대' WHEN DATEDIFF(day, birthday, GETDATE()) / 365 >= 90 THEN '90세 이상' END AS 연령대, * FROM person )Z GROUP BY 연령대, sex ORDER BY 1, 2 -- 엑셀에서 연령대별 성별별 시각화해보기 : shift+핸들바로 밀어올리기 활용 / 홈>스타일> 조건부서식 > 데이터 막대 --ethnicity 칼럼 SELECT TOP 100 ethnicity FROM person SELECT DISTINCT ethnicity FROM person SELECT COUNT(DISTINCT ethnicity) FROM person SELECT ethnicity, COUNT(personid) cnt FROM person GROUP BY ethnicity ORDER BY 1 --0 172 --1 18398 --drug 테이블-- drug personid drugdate druglocalcode atccode drugdept route duration SELECT COUNT(1) FROM drug --1890626 SELECT TOP 10 * FROM drug --key칼럼인 personid SELECT COUNT(DISTINCT personid) FROM person --18570 SELECT COUNT(DISTINCT personid) FROM drug --15430 약 안받은 환자 3100명 SELECT cast(15430 as float)/ cast(18570 as float) --0.830910070005385 = 83% SELECT 15430 * 1.0 / 18570 --범주형 drugdept SELECT TOP 100 drugdept FROM drug SELECT DISTINCT drugdept FROM drug -- I E H O SELECT COUNT(DISTINCT drugdept) FROM drug -- 범주 4가지 SELECT drugdept, COUNT(personid) cnt FROM drug GROUP BY drugdept ORDER BY 1 --E 82257 --H 1770 --I 1431086 --O 375513 SELECT drugdept, COUNT(DISTINCT personid) cnt FROM drug GROUP BY drugdept ORDER BY 1 --E 5298 --H 868 --I 8747 --O 11294 SELECT 82257+1770+1431086+375513 --1890626 == drug전체데이터 1890626 => null값 없음 SELECT * FROM drug WHERE drugdept IS NULL -- 범주형 route칼럼 SELECT TOP 100 route FROM drug SELECT DISTINCT route FROM drug --E P SELECT COUNT(DISTINCT route) FROM drug --2종류 SELECT route, COUNT(personid) cnt FROM drug GROUP BY route ORDER BY 1 --E 1176263 --P 714363 SELECT * FROM drug WHERE route IS NULL -- 범주형 같아보이지만 연속형 duration SELECT TOP 100 duration FROM drug SELECT DISTINCT duration FROM drug SELECT DISTINCT CONVERT(smallint, duration) "duration(int)" FROM drug --응용 -- ORDER BY 1 SELECT COUNT(DISTINCT duration) FROM drug --126종류 ALTER TABLE drug ALTER COLUMN duration int --칼럼 타입 변경 SELECT MIN(duration) min, MAX(duration) max, AVG(duration) avg FROM drug -- 0 390 7 --날짜(생년월일x) 칼럼 drugdate SELECT TOP 100 drugdate FROM drug ALTER TABLE drug ALTER COLUMN drugdate DATETIME --칼럼 타입 변경 SELECT MIN(drugdate) min, MAX(drugdate) max FROM drug --1994-06-24 00:00:00 2011-08-23 00:00:00 SELECT TOP 100 CONVERT(char(20), drugdate, 112) as YYYYmmdd, * FROM drug -- CONVERT 112 : YYYYmmdd SELECT TOP 100 SUBSTRING(CONVERT(char(20), drugdate, 112), 1, 4) as year FROM drug -- 필요시 SUBSTRING( CONVERT, 시작,이후갯수) ->: YYYY SELECT YYYYmmdd FROM ( SELECT CONVERT(char(20), drugdate, 112) as YYYYmmdd, * FROM drug )Z SELECT MIN(YYYYmmdd) min, MAX(YYYYmmdd) max FROM ( SELECT CONVERT(char(20), drugdate, 112) as YYYYmmdd, * FROM drug )Z SELECT YYYYmmdd year, COUNT(personid) FROM ( SELECT CONVERT(char(20), drugdate, 112) as YYYYmmdd, * FROM drug )Z GROUP BY YYYYmmdd ORDER BY 1 --연속형처럼보이는 범주형 code칼럼 : druglocalcode SELECT DISTINCT druglocalcode FROM drug -- 종류 너무 많음 SELECT COUNT(DISTINCT druglocalcode) FROM drug --2276 SELECT druglocalcode, COUNT(personid) cnt -- 범주의 종류가 많으면, 카운트 칼럼으로 머를 많이 썼는지 DESC ORDER BY FROM drug GROUP BY druglocalcode ORDER BY 2 DESC --Drug2069 27997 --Drug1472 23168 --Drug452 22800 --Drug2163 21542 --Drug2501 20501 SELECT * FROM DrugCodeMaster WHERE druglocalcode = 'Drug2069'; --Drug2069 Tramadol.HCl --1) SELECT drugigrname FROM DrugCodeMaster WHERE druglocalcode = 'Drug2069'; --2) SELECT drugigrname FROM DrugCodeMaster WHERE druglocalcode = druglocalcode; --3) SELECT (SELECT drugigrname FROM DrugCodeMaster dcm WHERE dcm.druglocalcode = d.druglocalcode) drugigrname, * FROM drug d --4) SELECT (SELECT drugigrname FROM DrugCodeMaster dcm WHERE dcm.druglocalcode = d.druglocalcode) drugigrname, d.druglocalcode, COUNT(personid) cnt FROM drug d GROUP BY d.druglocalcode ORDER BY 3 DESC --join SELECT * FROM Drug a JOIN DrugCodeMaster b ON a.druglocalcode = b.druglocalcode SELECT drugigrname, a.druglocalcode, COUNT(personid) cnt FROM Drug a JOIN DrugCodeMaster b ON a.druglocalcode = b.druglocalcode GROUP BY drugigrname, a.druglocalcode ORDER BY 3 DESC --연도별 처방빈도 SELECT SUBSTRING( CONVERT(varchar(8), drugdate,112), 1, 4) year, * FROM drug SELECT year, COUNT(personid) cnt FROM( SELECT SUBSTRING( CONVERT(varchar(8), drugdate,112), 1, 4) year, * FROM drug )Z GROUP BY year ORDER BY year DESC --월별별 처방빈도 SELECT months, COUNT(personid) cnt FROM( SELECT SUBSTRING( CONVERT(varchar(8), drugdate,112), 5, 2) months, * FROM drug )Z GROUP BY months ORDER BY months ASC -- 범주형칼럼 route SELECT TOP 100 route FROM drug SELECT DISTINCT route FROM drug SELECT COUNT(DISTINCT route) FROM drug SELECT route, COUNT(DISTINCT personid) cnt FROM drug GROUP BY route --E 14321 --P 12077 SELECT COUNT(DISTINCT personid) FROM drug -- 15430 사람수보다 E + P이 크다 = 교집합이 있다. SELECT * FROM drug WHERE route IS NULL --의미내포 범주형 code칼럼 : atccode SELECT TOP 100 atccode FROM drug SELECT COUNT(DISTINCT atccode) FROM drug --984 SELECT LEFT(atccode, 1) FROM drug SELECT LEFT(atccode, 1), * FROM drug SELECT -- 내포코드별 빈도확인 atc_1, COUNT(personid) cnt FROM( SELECT LEFT(atccode, 1) atc_1, * FROM drug )Z GROUP BY atc_1 ORDER BY 2 DESC -- 연도별 내포코드별 빈도확인 SELECT SUBSTRING(CONVERT(varchar(8), drugdate, 112), 1, 4) FROM drug SELECT year, atc_1, COUNT(personid) cnt FROM( SELECT SUBSTRING(CONVERT(varchar(8), drugdate, 112), 1, 4) year, LEFT(atccode, 1) atc_1, * FROM drug )Z GROUP BY year, atc_1 ORDER BY 1 ASC


서울대 연구공원 단지 내에 있는 SK TACACDEMY의 세미나를 다녀왔다.

시계열 데이터를 다루는 방법이 무척 궁금했는데

엄청 유용하게 쓰일 것 같다.

연습해야하는데 시간이 없다. ㅠ

낙성대역에서 관악2번타고 10분 정도 가면, 서울대 연구공원단지가 있음
거기에 삼성전자, LG, SK, COWAY 연구실이 다모여있었다. ㄷㄷ

중간에는 카페테리아 건물이 있어서 밥도 먹었다.

우아~~

MSSQL 의 sp_help(alt+F1)과 같은 기능은 존재하지 않는다.

SELECT *
FROM information_schema.columns
WHERE table_schema = 'your_schema'; --public
AND table_name = 'your_table'; --customers, purchases, items

위와 같은 구분으로 실행할 순 있다.

join

join은 python에서 set과 마찬가지다.
유니크한 요소들이 순서가 없다.
그러나, 이들은 교집합/ 합집합 / 여집합 계산이 가능하다는 장점이 있다.
SELECT * FROM 테이블1의 ON조건 대해서 INNER JOIN 테이블2의 ON조건테이블1에서부터 하나씩 검사하면서 교집합 있는 것들을 붙혀서 row단위로 나타낸다.

  1. INNER JOIN = 교집합
    1) SELECT * FROM 테이블1(Customers)로 다 보이게 할 건데,
    2) INNER JOIN 테이블2(Orders) 을 붙힐건데,

    3) ON 테이블1.id = 테이블2.id 로 교집합을 row를 붙힌다. 나는 테이블1의 ON인 id 1에 대해서 테이블2가 걸리는 것들을 검사해서 하나씩 붙힌다고 생각했다. 1-jose에 대해서, orders테이블에는 customer_id가 1인데 3개가 있으니 3개가 연달아 붙을 것이다.



    왼쪽테이블의 2는 걸리는게 없다.
    왼쪽테이블의 3-anna와 걸리는게 1개 있으니 붙힌다

  2. LEFT JOIN역시 인기가 많은 JOIN으로서,
    LEFT에 있는 테이블1은 모두 살리면서, 교집합을 검사하는데, 왼쪽테이블1으로 검사시 교집합이 없어도 BLANK(MSSQL : NULL)로 나타내면서 테이블1을 다 살린다.
    1) 테이블1을 기준으로 검사하는데 걸리는게 있으면 나타낸다.


    2) 만약 걸리는게 없어도, 테이블1은 살리면서 테이블2는 NULL로 나타낸다.

  3. RIGHT JOIN은 LEFT JOIN과 반대로, 오른쪽에서 검사를 시작하면서, 교집합이 없어도 오른쪽은 살리면 된다

  1. FULL JOIN은 교집합 + 여집합까지 다나타내는 것이다. LEFT JOIN과 RIGHT JOIN을 모두 생각해야한다. 왼1 -> 오1 -> 왼2 -> 오2 -> 순으로 하나씩 교집합과 여집합을 챙겨준다.
    1) 일단 나는 왼쪽테이블1에 대해 교집합을 찾고, 오른쪽테이블1은 교집합으로 물려갔으니 생각안한다.

    2) 왼쪽테이블2에 대해서는 교집합이 없으니 여집합으로서 나타낸다.

    3) 오른쪽테이블2에 대해서도 교집합이 없으니 여집합으로 챙긴다.

    4) 왼3에서는 교집합이 있으니 교집합으로 챙긴다.

    5) 오3은 이미 왼1로서 교집합으로 잡혀갔다.

    6) 왼4는 여집합으로서 챙긴다.

    7) 오4는 이미 교집합으로 잡혀갔다.

join examples

SELECT * FROM purchases; SELECT * FROM items; SELECT * FROM customers; -- 1) item들 중에 구매한 items 목록을 원하는 경우 SELECT * FROM items JOIN purchases ON items.id = purchases.id; -- left조인을 쓴다면, 구매하지 않은 아이템도 블랭크로 붙는다. SELECT * FROM items LEFT JOIN purchases ON items.id = purchases.id; -- 2) 이제 어느 고객이 어느 아이템을 샀는지 join해보자. SELECT * FROM customers JOIN purchases ON customers.id = purchases.customer_id; --left join SELECT * FROM customers LEFT JOIN purchases ON customers.id = purchases.customer_id; -- 고객 중에 구매를 한 고객 join데이터 중 이름만 select하기 SELECT customers.first\_name, customers.last_name FROM customers JOIN purchases ON customers.id = purchases.customer_id; -- 3) ***3개 테이블 한꺼번에 join해보기*** ---- (1) items중에 구매한 것들만 item만 나오도록 inner join한다. SELECT * FROM items INNER JOIN purchases ON items.id = purchases.item_id ---- (2) 여기서 보이는 customer\_id로 고객들을 연결할 수 있을 것이다. *** JOIN한것에 바로 JOIN을 해버린다. SELECT * FROM items INNER JOIN purchases ON items.id = purchases.item_id INNER JOIN customers ON purchases.customer_id = customers.id ---- (3) 필요한 칼럼만 챙겨보자. SELECT customers.first_name, customers.last_name, items.name, items.price FROM items INNER JOIN purchases ON items.id = purchases.item_id INNER JOIN customers ON purchases.customer\_id = customers.id


한* 선생님께서 통계 책을 빌려주셔서 쉽게 이해하였다.

일단 내가 조사한 설문지의 n수가 각각 6, 12, 111인데
이것들의 민감도, 특이도 수치를 비교하기 위해서는

3그룹이 ANOVA 아니면 Kruskal-Willis test 인 것 같다.
하지만, n수가 적어 정규분포를 따르지 않으므로 ANOVA를 제낀다.

  • K-W test는 정규분포를 따르지 않으니 3그룹 모두 크기별로 나열하고 순위를 정한 뒤, 순위의 합을 비교하는 방식이다.

비모수검정인 K-W test를 해서 p <0.05인 부분을 찾아봤는데
3가지 약재에서 1개만 집단별 차이를 보였다.

차이를 보인다면 사후검정을 해야한다.

사후검정의 종류를 찾아보니 Mann-whitney test가 있었다.

그 중 박사-한의사, 박사-학생만 차이를 보였다.

이것을 논문에 기술하는 것도 처음인데, 다른 논문을 참고하기가 쉽지가 않다.

그냥 pubmed에 해당 테스트를 사용한 figure를 몇개 찾은 뒤 종합해서 table을 만들고, 기술했다..

잘 될련지 모르겠다. ㅠ

'한의대 생활 > 본4 - SNUBI 인턴생활' 카테고리의 다른 글

01. 29 식권 대량구매  (0) 2019.01.30
01. 24 Pandas세미나 듣고옴  (0) 2019.01.24
01.14 R세미나 2번째 시간  (0) 2019.01.14
01. 09 ~ 11 Python 세미나 & DB 세미나  (0) 2019.01.11
01. 07 R 세미나1  (0) 2019.01.07

+ Recent posts