들어가기 전에 작은 시범조교를 하나(아니고 넷) 준비했음.. 다운 ㄱㄱ
각 csv파일의 내용물을 R로 불러오면
> df=read.csv('/home/koreanraichu/example.csv',sep=";")
> df
ID Interesred.in Class
1 kimlab0213 Python Basic
2 ahn_0526 Python Medium
3 peponi01 R Basic
4 kuda_koma R Expert
5 comma_life Java Basic
6 wheresjohn Java Medium
7 hanguk_joa Python Expert
8 sigma_00 R Basic
9 kokoatalk Java Basic
(example, 구분자 세미콜론)
> df2=read.csv('/home/koreanraichu/example2.csv')
> df2
ID Product.name Category.1 Category.2 Price Order Cancel
1 LB-001 LB agar Medium Bacteria 55000 5 0
2 LB-002 LB broth Medium Bacteria 50000 6 1
3 MS-001 MS agar Medium Plant 65000 7 2
4 MS-002 MS broth Medium Plant 60000 7 0
5 DM-001 DMEM Medium Cell culture 90000 20 0
6 BC-001 BCIG agar Medium Bacteria 70000 10 2
7 MS-003 MS agar(w/ plant hormone) Medium Plant 75000 2 1
8 PI-001 Pasteur pipet Consumable Experimental 10000 30 5
9 PI-002 Pipet-AID(10ml) Consumable Experimental 15000 45 0
10 PI-003 Pipet-AID(25ml) Consumable Experimental 25000 45 5
11 PI-004 Pipet-AID Equipment Experimental 100000 2 0
12 GL-001 Slide glass Glasswear Experimental 20000 50 0
13 GL-002 Cover glass Glasswear Experimental 20000 55 1
(example2, 구분자 콤마) 만들어놓고 잊혀진 파일
> df3=read.csv('/home/koreanraichu/example3.csv',sep="\t")
> df3
name Chemical.formula MW.g.mol.1. Density.g.cm.3.
1 Sodium chloride NaCl 58.443 2.17000
2 Acetic acid C2H4O2 60.052 1.04900
3 Glucose C6H12O6 180.156 1.54000
4 Mercury(II) sulfide HgS 232.660 8.10000
5 Toluene C7H8 92.141 0.87000
6 Phenol C6H6O 94.113 1.07000
7 Glycerol C3H8O3 92.094 1.26100
8 PETN C5H8N4O12 316.137 1.77000
9 Ethanol C2H6O 46.069 0.78945
10 SDS C12H25NaSO4 288.372 1.01000
11 Chlorophyll a C55H72MgN4O5 893.509 1.07900
12 Citric acid anhydrous C6H8O7 192.123 1.66500
13 Boron tribromide BBr3 250.520 2.64300
(example3, 구분자 탭)
> df4=read.csv('/home/koreanraichu/example4.csv',sep=" ")
> df4
category compound_name chemical_formula Molecular_mass.g.mol.1.
1 Borane Borane BH3 13.830
2 Borane Ammonia_borane BNH6 30.865
3 Borane Tetraborane B4H10 53.320
4 Borane Pentaborane(9) B5H9 63.120
5 Borane Octadecaborane B18H22 216.770
6 Oxide Caesium_monooxide Cs2O 281.810
7 Oxide Actinium_oxide Ac2O3 502.053
8 Oxide Triuranium_oxide U3O8 842.100
9 Oxide Technetium(VII)_oxide Tc2O7 307.810
10 Oxide Thorium_monooxide ThO 248.040
11 Alkane Methane CH4 16.043
12 Alkane Hexane C6H14 86.178
13 Alkane Nonane C9H20 128.259
14 Alkane Tridecane C13H28 184.367
15 Alkane Hentricotane C31H64 436.853
16 Sugar_alcohol Mannotol C6H14O6 182.172
17 Sugar_alcohol Xylitol C5H12O5 152.146
18 Sugar_alcohol Fucitol C6H14O5 166.170
19 Sugar_alcohol Volemitol C7H16O7 212.198
20 Sugar_alcohol Inositol C6H12O6 180.160
21 IARC_group_1 Aflatoxin_B1 C17H12O6 312.277
22 IARC_group_1 Cicloaporin C61H111N11O12 1202.635
23 IARC_group_1 Gallium_arsenide GaAs 144.615
24 IARC_group_1 Melphalan C13H18Cl2N2O2 305.200
25 IARC_group_1 Azothioprine C9H7N7O2S 277.260
(example4, 구분자 공백)
받아뒀다가 이거 할 때도 쓰고 판다스 할 때도 쓰세요. 참고로 해당 csv파일은 엑셀로도 열 수는 있지만 일단 만들 때는 지에딧으로 만들었음. (gedit filename.확장자 하면 그걸로 뜹디다)
Python과 R의 데이터프레임
-R은 데이터프레임을 다루기 위해 따로 뭘 깔 필요가 없다. 물론 일부 기능을 위해 plyr 라이브러리를 깔긴 해야 하지만 라이브러리 없이도 할 수는 있다. (python은 일단 판다스부터 깔고 봐야 한다)
-얘도 구분자 지정 안 해주면 default는 ,다. (위에 불러오는 코드를 보면 세미콜론과 탭, 공백은 따로 sep=""옵션을 줬다) 원래 csv의 cs가 comma seperated의 약자.
컬럼명 바꾸기
이번 시범조교는 2번 파일. 해당 파일의 컬럼명은
> names(df2)
[1] "ID" "Product.name" "Category.1" "Category.2" "Price"
[6] "Order" "Cancel"
이렇게 되어 있다.
우리의 신입사원 김부추씨는 저 csv파일을 받아서 R로 깔끔하게 정리를 했다. (order는 주문량, cancel은 주문 취소량) 그런데 중간보고를 위해 상급자에게 갔더니 상급자의 한마디!
"부추씨, 이거 정리 되게 깔끔하게 잘 했어. 그런데 저기 ID가 한번에 딱 봐서는 모를 것 같거든... ID만 Product ID로 바꿔서 제출하면 될 것 같아. "
김부추 멘붕왔다. 헐 그럼 csv파일단에서 수정 다시 해야 함? 이거 하느라 개고생했는데...OTL 근데 부추가 누구죠 아 제 텅비드 이름인데요 이제 텅비드를 취업시키는건가 아 걍 해요
> library(plyr)
> rename(df2,c("ID"="Product.ID"))
Product.ID Product.name Category.1 Category.2 Price Order
1 LB-001 LB agar Medium Bacteria 55000 5
2 LB-002 LB broth Medium Bacteria 50000 6
3 MS-001 MS agar Medium Plant 65000 7
4 MS-002 MS broth Medium Plant 60000 7
5 DM-001 DMEM Medium Cell culture 90000 20
6 BC-001 BCIG agar Medium Bacteria 70000 10
7 MS-003 MS agar(w/ plant hormone) Medium Plant 75000 2
8 PI-001 Pasteur pipet Consumable Experimental 10000 30
9 PI-002 Pipet-AID(10ml) Consumable Experimental 15000 45
10 PI-003 Pipet-AID(25ml) Consumable Experimental 25000 45
11 PI-004 Pipet-AID Equipment Experimental 100000 2
12 GL-001 Slide glass Glasswear Experimental 20000 50
13 GL-002 Cover glass Glasswear Experimental 20000 55
Cancel
1 0
2 1
3 2
4 0
5 0
6 2
7 1
8 5
9 0
10 5
11 0
12 0
13 1
파일단에서 손댈 것도 없이 그냥 저거 한 방이면 끝난다. (물론 plyr 라이브러리는 깔아두셨죠?) 참고로 얘는 저거 적용하고 names(df2)로 불러보면 ID로 나온다. (df2=코드 하고 해야 하나...)
네? 당장 보고 들어가야 해서 plyr 라이브러리 깔 시간이 없다고요?
> names(df2)[names(df2)=="ID"]="Product.ID"
> df2
Product.ID Product.name Category.1 Category.2 Price Order
1 LB-001 LB agar Medium Bacteria 55000 5
2 LB-002 LB broth Medium Bacteria 50000 6
3 MS-001 MS agar Medium Plant 65000 7
4 MS-002 MS broth Medium Plant 60000 7
5 DM-001 DMEM Medium Cell culture 90000 20
6 BC-001 BCIG agar Medium Bacteria 70000 10
7 MS-003 MS agar(w/ plant hormone) Medium Plant 75000 2
8 PI-001 Pasteur pipet Consumable Experimental 10000 30
9 PI-002 Pipet-AID(10ml) Consumable Experimental 15000 45
10 PI-003 Pipet-AID(25ml) Consumable Experimental 25000 45
11 PI-004 Pipet-AID Equipment Experimental 100000 2
12 GL-001 Slide glass Glasswear Experimental 20000 50
13 GL-002 Cover glass Glasswear Experimental 20000 55
Cancel
1 0
2 1
3 2
4 0
5 0
6 2
7 1
8 5
9 0
10 5
11 0
12 0
13 1
ㄱㄱ
> names(df2)=sub("ID","Product.ID",names(df2))
> df2
Product.Product.ID Product.name Category.1 Category.2 Price
1 LB-001 LB agar Medium Bacteria 55000
2 LB-002 LB broth Medium Bacteria 50000
3 MS-001 MS agar Medium Plant 65000
4 MS-002 MS broth Medium Plant 60000
5 DM-001 DMEM Medium Cell culture 90000
6 BC-001 BCIG agar Medium Bacteria 70000
7 MS-003 MS agar(w/ plant hormone) Medium Plant 75000
8 PI-001 Pasteur pipet Consumable Experimental 10000
9 PI-002 Pipet-AID(10ml) Consumable Experimental 15000
10 PI-003 Pipet-AID(25ml) Consumable Experimental 25000
11 PI-004 Pipet-AID Equipment Experimental 100000
12 GL-001 Slide glass Glasswear Experimental 20000
13 GL-002 Cover glass Glasswear Experimental 20000
Order Cancel
1 5 0
2 6 1
3 7 2
4 7 0
5 20 0
6 10 2
7 2 1
8 30 5
9 45 0
10 45 5
11 2 0
12 50 0
13 55 1
> names(df2)=gsub("D","d",names(df2))
> df2
Product.Product.Id Product.name Category.1 Category.2 Price
1 LB-001 LB agar Medium Bacteria 55000
2 LB-002 LB broth Medium Bacteria 50000
3 MS-001 MS agar Medium Plant 65000
4 MS-002 MS broth Medium Plant 60000
5 DM-001 DMEM Medium Cell culture 90000
6 BC-001 BCIG agar Medium Bacteria 70000
7 MS-003 MS agar(w/ plant hormone) Medium Plant 75000
8 PI-001 Pasteur pipet Consumable Experimental 10000
9 PI-002 Pipet-AID(10ml) Consumable Experimental 15000
10 PI-003 Pipet-AID(25ml) Consumable Experimental 25000
11 PI-004 Pipet-AID Equipment Experimental 100000
12 GL-001 Slide glass Glasswear Experimental 20000
13 GL-002 Cover glass Glasswear Experimental 20000
Order Cancel
1 5 0
2 6 1
3 7 2
4 7 0
5 20 0
6 10 2
7 2 1
8 30 5
9 45 0
10 45 5
11 2 0
12 50 0
13 55 1
sub(), gsub()도 당연히 된다. (라이브러리 없어도 됨)
컬럼 첨삭하기
> df
ID Interesred.in Class
1 kimlab0213 Python Basic
2 ahn_0526 Python Medium
3 peponi01 R Basic
4 kuda_koma R Expert
5 comma_life Java Basic
6 wheresjohn Java Medium
7 hanguk_joa Python Expert
8 sigma_00 R Basic
9 kokoatalk Java Basic
example 1번을 모셔봅시다. 예제 1번은 회원들에게 프로그래밍 언어 강의를 제공하는 웹 플랫폼을 상정하고 만든 것이다. (그래서 파이썬 R 자바가... 씨언어 어디갔어요 씨언어 뭐 씨? 씨샵? 씨쁠쁠?) 그러니까 ID는 회원 아이디, 관심분야는 파이썬, 클래스는 강의의 난이도(초급/중급/전문가).
씁 근데 이렇게만 해서는 이 아이디의 주인이 해당 수업을 다 이수했나 아닌가를 모르겠다. 그래서 P/F 컬럼을 새로 추가하고자 한다.
> df$PF=c("P","P","F","F","P","F","P","F","F")
> df
ID Interesred.in Class PF
1 kimlab0213 Python Basic P
2 ahn_0526 Python Medium P
3 peponi01 R Basic F
4 kuda_koma R Expert F
5 comma_life Java Basic P
6 wheresjohn Java Medium F
7 hanguk_joa Python Expert P
8 sigma_00 R Basic F
9 kokoatalk Java Basic F
제목이요? 저거는 따옴표로 감싸지 않는 이상 공백 있으면 에러뜸미다... (언더바 ㄱㄱ)
> df[,"Pass or Fail"]=c("P","P","F","F","P","F","P","F","F")
> df
ID Interesred.in Class Pass or Fail
1 kimlab0213 Python Basic P
2 ahn_0526 Python Medium P
3 peponi01 R Basic F
4 kuda_koma R Expert F
5 comma_life Java Basic P
6 wheresjohn Java Medium F
7 hanguk_joa Python Expert P
8 sigma_00 R Basic F
9 kokoatalk Java Basic F
아니면 이건 어떠심?
그렇게 아이디어를 제안한 김상추씨. 하지만 선배 김양상추씨(둘 다 본인 포켓몬 이름임... 릴리요였나...)는 그 제안을 듣고 이렇게 말했다.
"좋은 아이디어긴 한데... P/F로 매기게 되면 강의 이수여부는 알 수 있지만, 출결 관리까지 알기는 좀 힘들 것 같아. 차라리 P/F를 빼고 출석율을 넣거나, 출석율이랑 병기하는 건 어때? "
> df$PF=NULL
> df
ID Interesred.in Class
1 kimlab0213 Python Basic
2 ahn_0526 Python Medium
3 peponi01 R Basic
4 kuda_koma R Expert
5 comma_life Java Basic
6 wheresjohn Java Medium
7 hanguk_joa Python Expert
8 sigma_00 R Basic
9 kokoatalk Java Basic
그래서 김상추씨는 PF 컬럼을 빼버렸다.
참고로
# Ways to add a column
data$size <- c("small", "large", "medium")
data[["size"]] <- c("small", "large", "medium")
data[,"size"] <- c("small", "large", "medium")
data$size <- 0 # Use the same value (0) for all rows
# Ways to remove the column
data$size <- NULL
data[["size"]] <- NULL
data[,"size"] <- NULL
data[[3]] <- NULL
data[,3] <- NULL
data <- subset(data, select=-size)
이건 뭐 니들이 뭘 좋아할 지 몰라서 다 넣었어도 아니고 첨삭 방법이 되게 많다.
컬럼 오더 바꾸기
이번 시범조교...
> df3
name Chemical.formula MW.g.mol.1. Density.g.cm.3.
1 Sodium chloride NaCl 58.443 2.17000
2 Acetic acid C2H4O2 60.052 1.04900
3 Glucose C6H12O6 180.156 1.54000
4 Mercury(II) sulfide HgS 232.660 8.10000
5 Toluene C7H8 92.141 0.87000
6 Phenol C6H6O 94.113 1.07000
7 Glycerol C3H8O3 92.094 1.26100
8 PETN C5H8N4O12 316.137 1.77000
9 Ethanol C2H6O 46.069 0.78945
10 SDS C12H25NaSO4 288.372 1.01000
11 Chlorophyll a C55H72MgN4O5 893.509 1.07900
12 Citric acid anhydrous C6H8O7 192.123 1.66500
13 Boron tribromide BBr3 250.520 2.64300
이분임...
보기만 해도 으아아가 절로 나온다면 정상입니다. 난 아니지만. 이사람 집에 주기율표 있다 끝말잇기 잘하시겠네요 아뇨 그건 아닙니다 원래 주기율표 다 꿰고 있으면 완급조절도 가능하다 코페르니슘! 슘페터! 터븀!
> df3[c(4,3,2,1)]
Density.g.cm.3. MW.g.mol.1. Chemical.formula name
1 2.17000 58.443 NaCl Sodium chloride
2 1.04900 60.052 C2H4O2 Acetic acid
3 1.54000 180.156 C6H12O6 Glucose
4 8.10000 232.660 HgS Mercury(II) sulfide
5 0.87000 92.141 C7H8 Toluene
6 1.07000 94.113 C6H6O Phenol
7 1.26100 92.094 C3H8O3 Glycerol
8 1.77000 316.137 C5H8N4O12 PETN
9 0.78945 46.069 C2H6O Ethanol
10 1.01000 288.372 C12H25NaSO4 SDS
11 1.07900 893.509 C55H72MgN4O5 Chlorophyll a
12 1.66500 192.123 C6H8O7 Citric acid anhydrous
13 2.64300 250.520 BBr3 Boron tribromide
오더를 이렇게 컬럼명으로 바꾸거나(...)
> df3[c("Chemical.formula","name","MW.g.mol.1.","Density.g.cm.3.")]
Chemical.formula name MW.g.mol.1. Density.g.cm.3.
1 NaCl Sodium chloride 58.443 2.17000
2 C2H4O2 Acetic acid 60.052 1.04900
3 C6H12O6 Glucose 180.156 1.54000
4 HgS Mercury(II) sulfide 232.660 8.10000
5 C7H8 Toluene 92.141 0.87000
6 C6H6O Phenol 94.113 1.07000
7 C3H8O3 Glycerol 92.094 1.26100
8 C5H8N4O12 PETN 316.137 1.77000
9 C2H6O Ethanol 46.069 0.78945
10 C12H25NaSO4 SDS 288.372 1.01000
11 C55H72MgN4O5 Chlorophyll a 893.509 1.07900
12 C6H8O7 Citric acid anhydrous 192.123 1.66500
13 BBr3 Boron tribromide 250.520 2.64300
...일단 저건 숫자가 더 효율적임.
> df3[,c(1,2,4,3)]
name Chemical.formula Density.g.cm.3. MW.g.mol.1.
1 Sodium chloride NaCl 2.17000 58.443
2 Acetic acid C2H4O2 1.04900 60.052
3 Glucose C6H12O6 1.54000 180.156
4 Mercury(II) sulfide HgS 8.10000 232.660
5 Toluene C7H8 0.87000 92.141
6 Phenol C6H6O 1.07000 94.113
7 Glycerol C3H8O3 1.26100 92.094
8 PETN C5H8N4O12 1.77000 316.137
9 Ethanol C2H6O 0.78945 46.069
10 SDS C12H25NaSO4 1.01000 288.372
11 Chlorophyll a C55H72MgN4O5 1.07900 893.509
12 Citric acid anhydrous C6H8O7 1.66500 192.123
13 Boron tribromide BBr3 2.64300 250.520
뭔 매트릭스 매기듯이 이렇게도 한다.
> df3[2]
Chemical.formula
1 NaCl
2 C2H4O2
3 C6H12O6
4 HgS
5 C7H8
6 C6H6O
7 C3H8O3
8 C5H8N4O12
9 C2H6O
10 C12H25NaSO4
11 C55H72MgN4O5
12 C6H8O7
13 BBr3
2열을 뽑아봤습니다.
> df3[,2]
[1] NaCl C2H4O2 C6H12O6 HgS C7H8
[6] C6H6O C3H8O3 C5H8N4O12 C2H6O C12H25NaSO4
[11] C55H72MgN4O5 C6H8O7 BBr3
13 Levels: BBr3 C12H25NaSO4 C2H4O2 C2H6O C3H8O3 C55H72MgN4O5 ... NaCl
이렇게 하면 벡터처럼 뽑힌다. (레벨이 있는 걸 보면 아시겠지만 팩터임)
> df3[,2,drop=FALSE]
Chemical.formula
1 NaCl
2 C2H4O2
3 C6H12O6
4 HgS
5 C7H8
6 C6H6O
7 C3H8O3
8 C5H8N4O12
9 C2H6O
10 C12H25NaSO4
11 C55H72MgN4O5
12 C6H8O7
13 BBr3
drop=FALSE를 주면 표 형태로 뽑힌다. 저게 그 시리즌가 그거냐 그건 판다스고
파이널 퓨전
> df
ID Interesred.in Class Pass or Fail
1 kimlab0213 Python Basic P
2 ahn_0526 Python Medium P
3 peponi01 R Basic F
4 kuda_koma R Expert F
5 comma_life Java Basic P
6 wheresjohn Java Medium F
7 hanguk_joa Python Expert P
8 sigma_00 R Basic F
9 kokoatalk Java Basic F
아까 그거 맞다. 여기에다가 클래스별 가격 정보를 추가할건데... 그럼 가격표가 어디 있느냐고?
> df5=read.table(header=TRUE, text='
+ Class;Price
+ Basic;Free
+ Medium;1000
+ Expert;2000
+ ',sep=";")
> df5
Class Price
1 Basic Free
2 Medium 1000
3 Expert 2000
여기요.
이 표를 파이널(별)퓨전해달라는 업무를 받은 김상추씨(아니 진짜 내 포켓몬 이름이여 이름이 왜그래요 부추때문에 추로 끝나는 야채는 다 넣었음 다행히도 고추는 없습니다 그건 어감이 거시기해서)... 아니 그럼 새로 컬럼 만들고 저걸 일일이 다 써요? ㄴㄴ
> merge(df,df5,"Class")
Class ID Interesred.in Pass or Fail Price
1 Basic kimlab0213 Python P Free
2 Basic peponi01 R F Free
3 Basic sigma_00 R F Free
4 Basic comma_life Java P Free
5 Basic kokoatalk Java F Free
6 Expert hanguk_joa Python P 2000
7 Expert kuda_koma R F 2000
8 Medium ahn_0526 Python P 1000
9 Medium wheresjohn Java F 1000
공통된 컬럼인 Class를 기반으로 파이널퓨전 하면 된다.
> df6[c(3,4,5,1,2)]
ID Interesred.in Pass or Fail Class Price
1 kimlab0213 Python P Basic Free
2 peponi01 R F Basic Free
3 sigma_00 R F Basic Free
4 comma_life Java P Basic Free
5 kokoatalk Java F Basic Free
6 hanguk_joa Python P Expert 2000
7 kuda_koma R F Expert 2000
8 ahn_0526 Python P Medium 1000
9 wheresjohn Java F Medium 1000
새 데이터프레임에 할당하고 순서 바꿀 수 있다.
> stories2 <- read.table(header=TRUE, text='
+ id title
+ 1 lions
+ 2 tigers
+ 3 bears
+ ')
subject storyid rating
1 1 1 6.7
2 1 2 4.5
3 1 3 3.7
4 2 2 3.3
5 2 3 4.1
6 2 1 5.2
컬럼명이 다른데 되나요?
> merge(x=stories2,y=data,by.x="id",by.y="storyid")
id title subject rating
1 1 lions 1 6.7
2 1 lions 2 5.2
3 2 tigers 1 4.5
4 2 tigers 2 3.3
5 3 bears 1 3.7
6 3 bears 2 4.1
네. 근데 내가 갖고 있는거에 만들어서 할랬더니 에러뜸...
Error in fix.by(by.x, x) : 'by' must specify a uniquely valid column
혹시 이 에러 해결법 아시는 분 제보좀 부탁드립니다. (합치려는 데이터프레임 영역 팩터로 같은 거 확인함)
> animals <- read.table(header=T, text='
+ size type name
+ small cat lynx
+ big cat tiger
+ small dog chihuahua
+ big dog "great dane"
+ ')
> observations <- read.table(header=T, text='
+ number size type
+ 1 big cat
+ 2 small dog
+ 3 small dog
+ 4 big dog
+ ')
이걸 파이널퓨전하는 것도 된다.
> merge(observations,animals,c("size","type"))
size type number name
1 big cat 1 tiger
2 big dog 4 great dane
3 small dog 2 chihuahua
4 small dog 3 chihuahua
어째서인지는 모르겠으나 됨.
데이터프레임 비교하기
> dfA <- data.frame(Subject=c(1,1,2,2), Response=c("X","X","X","X"))
> dfB <- data.frame(Subject=c(1,2,3), Response=c("X","Y","X"))
> dfC <- data.frame(Subject=c(1,2,3), Response=c("Z","Y","Z"))
> dfA
Subject Response
1 1 X
2 1 X
3 2 X
4 2 X
> dfB
Subject Response
1 1 X
2 2 Y
3 3 X
> dfC
Subject Response
1 1 Z
2 2 Y
3 3 Z
쿡북에 있는 시범조교를 모셔봤습니다.
> dfA$Coder="A"
> dfB$Coder="B"
> dfC$Coder="C"
각 데이터프레임에 Coder라는 컬럼을 추가한다.
> df7=rbind(dfA,dfB,dfC)
> df7
Subject Response Coder
1 1 X A
2 1 X A
3 2 X A
4 2 X A
5 1 X B
6 2 Y B
7 3 X B
8 1 Z C
9 2 Y C
10 3 Z C
그리고 행단위로 파이널퓨전!
> df7=df7[,c("Coder","Subject","Response")]
> df7
Coder Subject Response
1 A 1 X
2 A 1 X
3 A 2 X
4 A 2 X
5 B 1 X
6 B 2 Y
7 B 3 X
8 C 1 Z
9 C 2 Y
10 C 3 Z
하고 정렬까지 해야 시범조교 끝...
참고로 이걸 진행하려면 함수 하나를 정의하고 가야 하는데
dupsBetweenGroups <- function (df, idcol) {
# df: the data frame
# idcol: the column which identifies the group each row belongs to
# Get the data columns to use for finding matches
datacols <- setdiff(names(df), idcol)
# Sort by idcol, then datacols. Save order so we can undo the sorting later.
sortorder <- do.call(order, df)
df <- df[sortorder,]
# Find duplicates within each id group (first copy not marked)
dupWithin <- duplicated(df)
# With duplicates within each group filtered out, find duplicates between groups.
# Need to scan up and down with duplicated() because first copy is not marked.
dupBetween = rep(NA, nrow(df))
dupBetween[!dupWithin] <- duplicated(df[!dupWithin,datacols])
dupBetween[!dupWithin] <- duplicated(df[!dupWithin,datacols], fromLast=TRUE) | dupBetween[!dupWithin]
# ============= Replace NA's with previous non-NA value ==============
# This is why we sorted earlier - it was necessary to do this part efficiently
# Get indexes of non-NA's
goodIdx <- !is.na(dupBetween)
# These are the non-NA values from x only
# Add a leading NA for later use when we index into this vector
goodVals <- c(NA, dupBetween[goodIdx])
# Fill the indices of the output vector with the indices pulled from
# these offsets of goodVals. Add 1 to avoid indexing to zero.
fillIdx <- cumsum(goodIdx)+1
# The original vector, now with gaps filled
dupBetween <- goodVals[fillIdx]
# Undo the original sort
dupBetween[sortorder] <- dupBetween
# Return the vector of which entries are duplicated across groups
return(dupBetween)
}
이놈이다. 정의하고 가자.
> dupRows=dupsBetweenGroups(df7,"Coder")
> dupRows
[1] TRUE TRUE FALSE FALSE TRUE TRUE FALSE FALSE TRUE FALSE
근데 이렇게만 해 두면 뭔지 모르것다...
> cbind(df7,dup=dupRows)
Coder Subject Response dup
1 A 1 X TRUE
2 A 1 X TRUE
3 A 2 X FALSE
4 A 2 X FALSE
5 B 1 X TRUE
6 B 2 Y TRUE
7 B 3 X FALSE
8 C 1 Z FALSE
9 C 2 Y TRUE
10 C 3 Z FALSE
열단위로 결합해도 뭔지 모르겠다...
사실 저건 각 테이블에서 중복되는 값을 찾아주는 함수이다. 코드가 달라도 중복되는 값이 있으면 TRUE, 아예 없으면 FALSE.
> cbind(df7,unique=!dupRows)
Coder Subject Response unique
1 A 1 X FALSE
2 A 1 X FALSE
3 A 2 X TRUE
4 A 2 X TRUE
5 B 1 X FALSE
6 B 2 Y FALSE
7 B 3 X TRUE
8 C 1 Z TRUE
9 C 2 Y FALSE
10 C 3 Z TRUE
이건 반대로 중복이 없으면 TRUE, 중복값이 있으면 FALSE다.
서브셋 나누기
> dfA=subset(dfDup,Coder=="A",select=-Coder)
> dfB=subset(dfDup,Coder=="B",select=-Coder)
> dfC=subset(dfDup,Coder=="C",select=-Coder)
> dfA
Subject Response dup
1 1 X TRUE
2 1 X TRUE
3 2 X FALSE
4 2 X FALSE
> dfB
Subject Response dup
5 1 X TRUE
6 2 Y TRUE
7 3 X FALSE
> dfC
Subject Response dup
8 1 Z FALSE
9 2 Y TRUE
10 3 Z FALSE
# 아 저게 Coder 빼고 셀렉션해달라는 얘기였냐고
나누면 됩니다. 근데 저 셀렉트는 뭐냐...
> df4
category compound_name chemical_formula Molecular_mass.g.mol.1.
1 Borane Borane BH3 13.830
2 Borane Ammonia_borane BNH6 30.865
3 Borane Tetraborane B4H10 53.320
4 Borane Pentaborane(9) B5H9 63.120
5 Borane Octadecaborane B18H22 216.770
6 Oxide Caesium_monooxide Cs2O 281.810
7 Oxide Actinium_oxide Ac2O3 502.053
8 Oxide Triuranium_oxide U3O8 842.100
9 Oxide Technetium(VII)_oxide Tc2O7 307.810
10 Oxide Thorium_monooxide ThO 248.040
11 Alkane Methane CH4 16.043
12 Alkane Hexane C6H14 86.178
13 Alkane Nonane C9H20 128.259
14 Alkane Tridecane C13H28 184.367
15 Alkane Hentricotane C31H64 436.853
16 Sugar_alcohol Mannotol C6H14O6 182.172
17 Sugar_alcohol Xylitol C5H12O5 152.146
18 Sugar_alcohol Fucitol C6H14O5 166.170
19 Sugar_alcohol Volemitol C7H16O7 212.198
20 Sugar_alcohol Inositol C6H12O6 180.160
21 IARC_group_1 Aflatoxin_B1 C17H12O6 312.277
22 IARC_group_1 Cicloaporin C61H111N11O12 1202.635
23 IARC_group_1 Gallium_arsenide GaAs 144.615
24 IARC_group_1 Melphalan C13H18Cl2N2O2 305.200
25 IARC_group_1 Azothioprine C9H7N7O2S 277.260
시범조교 4번을 불러보자. 으아아 저게 뭐야 참고로 IARC group 1은 이놈은 Carcinogen(발암물질)이 확실하니까 먹지도 마시지도 말고 애비 지지해야되는 것들.
> df4A=subset(df4,category=="Borane")
> df4A
category compound_name chemical_formula Molecular_mass.g.mol.1.
1 Borane Borane BH3 13.830
2 Borane Ammonia_borane BNH6 30.865
3 Borane Tetraborane B4H10 53.320
4 Borane Pentaborane(9) B5H9 63.120
5 Borane Octadecaborane B18H22 216.770
Borane(붕소 화합물임... 자세한건 모름)으로 서브셋을 만들어보면 이렇게 나온다. 근데 생각해보니 Borane으로 묶었는데 저기서 카테고리를 보여 줄 필요가 없거든.
> df4B=subset(df4,category=="IARC_group_1",select=-category)
> df4B
compound_name chemical_formula Molecular_mass.g.mol.1.
21 Aflatoxin_B1 C17H12O6 312.277
22 Cicloaporin C61H111N11O12 1202.635
23 Gallium_arsenide GaAs 144.615
24 Melphalan C13H18Cl2N2O2 305.200
25 Azothioprine C9H7N7O2S 277.260
그래서 select에 -를 줘서 뺀 것이다. (R에서 -붙으면 그거 빼고 달라는 얘기)
> df4C=subset(df4,Molecular_mass.g.mol.1.>=100)
> df4C
category compound_name chemical_formula Molecular_mass.g.mol.1.
5 Borane Octadecaborane B18H22 216.770
6 Oxide Caesium_monooxide Cs2O 281.810
7 Oxide Actinium_oxide Ac2O3 502.053
8 Oxide Triuranium_oxide U3O8 842.100
9 Oxide Technetium(VII)_oxide Tc2O7 307.810
10 Oxide Thorium_monooxide ThO 248.040
13 Alkane Nonane C9H20 128.259
14 Alkane Tridecane C13H28 184.367
15 Alkane Hentricotane C31H64 436.853
16 Sugar_alcohol Mannotol C6H14O6 182.172
17 Sugar_alcohol Xylitol C5H12O5 152.146
18 Sugar_alcohol Fucitol C6H14O5 166.170
19 Sugar_alcohol Volemitol C7H16O7 212.198
20 Sugar_alcohol Inositol C6H12O6 180.160
21 IARC_group_1 Aflatoxin_B1 C17H12O6 312.277
22 IARC_group_1 Cicloaporin C61H111N11O12 1202.635
23 IARC_group_1 Gallium_arsenide GaAs 144.615
24 IARC_group_1 Melphalan C13H18Cl2N2O2 305.200
25 IARC_group_1 Azothioprine C9H7N7O2S 277.260
참고로 조건부로 서브셋 만드는 것도 된다. 뭐 여기서는 100으로 잡았지만 ChEMBL에서 불러온 다음 RO5 조건 만족하는 것들로 만들거나 BBB 통과 조건으로 만들거나 할 수도 있다. (아니면 SMILES에 @@ 붙은거?)
팩터 레벨 재조정하기
그 뮤츠씨가 좋아하는? 아니 그건 팩트라니까 얘는 팩터잖아
> str(df3)
'data.frame': 13 obs. of 4 variables:
$ name : Factor w/ 13 levels "Acetic acid",..: 12 1 6 8 13 10 7 9 5 11 ...
$ Chemical.formula: Factor w/ 13 levels "BBr3","C12H25NaSO4",..: 13 3 8 12 11 9 5 7 4 2 ...
$ MW.g.mol.1. : num 58.4 60.1 180.2 232.7 92.1 ...
$ Density.g.cm.3. : num 2.17 1.05 1.54 8.1 0.87 ...
3번 시범조교에도 팩터가 두 개 있다. (이름, 분자식) ㅇㅋ? ㄱㄱ
> df3_1=droplevels(df3)
> df3_1
name Chemical.formula MW.g.mol.1. Density.g.cm.3.
1 Sodium chloride NaCl 58.443 2.17000
2 Acetic acid C2H4O2 60.052 1.04900
3 Glucose C6H12O6 180.156 1.54000
4 Mercury(II) sulfide HgS 232.660 8.10000
5 Toluene C7H8 92.141 0.87000
6 Phenol C6H6O 94.113 1.07000
7 Glycerol C3H8O3 92.094 1.26100
8 PETN C5H8N4O12 316.137 1.77000
9 Ethanol C2H6O 46.069 0.78945
10 SDS C12H25NaSO4 288.372 1.01000
11 Chlorophyll a C55H72MgN4O5 893.509 1.07900
13 Boron tribromide BBr3 250.520 2.64300
12행을 날리고 droplevel()을 적용하면
> str(df3_1)
'data.frame': 12 obs. of 4 variables:
$ name : Factor w/ 12 levels "Acetic acid",..: 11 1 5 7 12 9 6 8 4 10 ...
$ Chemical.formula: Factor w/ 12 levels "BBr3","C12H25NaSO4",..: 12 3 8 11 10 9 5 7 4 2 ...
$ MW.g.mol.1. : num 58.4 60.1 180.2 232.7 92.1 ...
$ Density.g.cm.3. : num 2.17 1.05 1.54 8.1 0.87 ...
팩터 레벨이 바뀌었다. (13->12)
이걸 vapply()와 lapply()를 적용해서 할 수도 있는데
> factor_cols=vapply(df3,is.factor,logical(1))
> factor_cols
name Chemical.formula MW.g.mol.1. Density.g.cm.3.
TRUE TRUE FALSE FALSE
vapply()를 통해 이놈이 팩터인가를 볼 수 있고
> df3[factor_cols]=lapply(df3[factor_cols],factor)
# Apply the factor() function to those columns, and assign then back into d
팩터 함수를 적용시키면
> str(df3)
'data.frame': 12 obs. of 4 variables:
$ name : Factor w/ 12 levels "Acetic acid",..: 11 1 5 7 12 9 6 8 4 10 ...
$ Chemical.formula: Factor w/ 12 levels "BBr3","C12H25NaSO4",..: 12 3 8 11 10 9 5 7 4 2 ...
$ MW.g.mol.1. : num 58.4 60.1 180.2 232.7 92.1 ...
$ Density.g.cm.3. : num 2.17 1.05 1.54 8.1 0.87 ...
(대충 droplevel()이랑 같은거라는 얘기)
'Coding > R' 카테고리의 다른 글
R 배워보기- 6.5. Manipulating data-Sequential data (0) | 2022.08.20 |
---|---|
R 배워보기- 6.4. Manipulating data-Restructing data (0) | 2022.08.20 |
R 배워보기- 6.2. Manipulating data-Factors (0) | 2022.08.20 |
R 배워보기- 6.1. Manipulating data-General (0) | 2022.08.20 |
R 배워보기-5. 데이터 불러오고 쓰기 (0) | 2022.08.20 |