유전 평가하고 상관 없으나 혈통이 있을 때 부모 또는 자식으로 연결하였을 때 몇 개의 그룹으로 나누어질지 궁금할 때가 있다. 물론 그림을 그리면 되긴 하지만, 몇십 개 이상은 그림을 그리기가 힘들다. 물론 포트란 소스로 올린 적도 있으나 컴파일하기도 힘들어서 누가 쓸까 싶다. 그래서 간단히 R로 만들어 보았다. 포트란보다 많이 느리겠지만 ...
먼저 혈통 자료
animal,sire,dam
a1,0,0
a2,0,0
a3,0,0
a4,0,0
a9,0,0
a10,0,0
a11,0,0
a14,0,0
a5,a1,a2
a6,a3,a4
a7,a5,a6
a12,a9,a10
a13,a12,a11
a8,a5,a7
그림을 그려 보면 세 개의 그룹으로 이루어진 것을 알 수 있다.
R 소스
#
# group.R
#
# 혈통 자료 읽기
pedi <-
read.table(
"pedi_group.csv",
header = TRUE,
sep = ",",
stringsAsFactors = FALSE
)
pedi
pedi2 = cbind(pedi, flag = rep(0, nrow(pedi)), group = rep(0, nrow(pedi)))
pedi2
group_num = 0
# pedi2 파일의 개체 하나씩 처리하기
for (i in 1:nrow(pedi2)) {
# 처리한 개체가 아니라면
if (pedi2[i, "flag"] == 0) {
#group_num 증가
group_num = group_num + 1
# pedi2 파일의 개체를 temp에 넣기
temp = data.frame(animal = pedi2[i, "animal"], stringsAsFactors = FALSE)
# temp를 읽어 내려가면 처리하기
j = 1
while (j <= nrow(temp)) {
# temp의 개체가 pedi에 존재하는가 그리고 처리를 안 했는가
index = which(pedi2$animal == temp[j, "animal"])
if (length(index) != 0 &&
pedi2[index, "flag"] == 0) {
# pedid2에 개체를 처리했다고 표시(flag)
pedi2[index, "flag"] = 1
# pedid2에 group_num 입력
pedi2[index, "group"] = group_num
# 개체의 아비 찾기
sire = pedi2[index, "sire"]
# 아비가 있다면
if (sire != 0) {
# temp에 sire 추가
temp = rbind(temp, sire)
}
# 개체의 어미 찾기
dam = pedi2[index, "dam"]
# 어미가 있다면
if (dam != 0) {
# temp에 dam 추가
temp = rbind(temp, dam)
}
# 아비라고 생각하고 자식 찾기
index = which(pedi2$sire == temp[j, "animal"] & pedi2[which(pedi2$sire == temp[j, "animal"]), "flag"] == 0)
progeny = as.data.frame(pedi2[index, "animal"])
names(progeny) = names(temp)
temp = rbind(temp, progeny)
# 어미라고 생각하고 자식 찾기
index = which(pedi2$dam == temp[j, "animal"] & pedi2[which(pedi2$dam == temp[j, "animal"]), "flag"] == 0)
progeny = as.data.frame(pedi2[index, "animal"])
names(progeny) = names(temp)
temp = rbind(temp, progeny)
# 1000개마다 처리 중임을 표시
if( (j %% 1000) == 1 ){
print(paste("Group " , group_num , ": ", j, " processing"))
}
}
j = j + 1
}
}
}
pedi2 = pedi2[order(pedi2$group), ]
pedi2
실행 결과
> # 혈통 자료 읽기
> pedi <-
+ read.table(
+ "pedi_group.csv",
+ header = TRUE,
+ sep = ",",
+ stringsAsFactors = FALSE
+ )
> pedi
animal sire dam
1 a1 0 0
2 a2 0 0
3 a3 0 0
4 a4 0 0
5 a9 0 0
6 a10 0 0
7 a11 0 0
8 a14 0 0
9 a5 a1 a2
10 a6 a3 a4
11 a7 a5 a6
12 a12 a9 a10
13 a13 a12 a11
14 a8 a5 a7
>
> pedi2 = cbind(pedi, flag = rep(0, nrow(pedi)), group = rep(0, nrow(pedi)))
> pedi2
animal sire dam flag group
1 a1 0 0 0 0
2 a2 0 0 0 0
3 a3 0 0 0 0
4 a4 0 0 0 0
5 a9 0 0 0 0
6 a10 0 0 0 0
7 a11 0 0 0 0
8 a14 0 0 0 0
9 a5 a1 a2 0 0
10 a6 a3 a4 0 0
11 a7 a5 a6 0 0
12 a12 a9 a10 0 0
13 a13 a12 a11 0 0
14 a8 a5 a7 0 0
>
> group_num = 0
> # pedi2 파일의 개체 하나씩 처리하기
> for (i in 1:nrow(pedi2)) {
+
+ # 처리한 개체가 아니라면
+ if (pedi2[i, "flag"] == 0) {
+
+ #group_num 증가
+ group_num = group_num + 1
+
+ # pedi2 파일의 개체를 temp에 넣기
+ temp = data.frame(animal = pedi2[i, "animal"], stringsAsFactors = FALSE)
+
+ # temp를 읽어 내려가면 처리하기
+ j = 1
+ while (j <= nrow(temp)) {
+
+ # temp의 개체가 pedi에 존재하는가 그리고 처리를 안 했는가
+ index = which(pedi2$animal == temp[j, "animal"])
+ if (length(index) != 0 &&
+ pedi2[index, "flag"] == 0) {
+ # pedid2에 개체를 처리했다고 표시(flag)
+ pedi2[index, "flag"] = 1
+
+ # pedid2에 group_num 입력
+ pedi2[index, "group"] = group_num
+
+ # 개체의 아비 찾기
+ sire = pedi2[index, "sire"]
+
+ # 아비가 있다면
+ if (sire != 0) {
+ # temp에 sire 추가
+ temp = rbind(temp, sire)
+ }
+
+ # 개체의 어미 찾기
+ dam = pedi2[index, "dam"]
+
+ # 어미가 있다면
+ if (dam != 0) {
+ # temp에 dam 추가
+ temp = rbind(temp, dam)
+ }
+
+ # 아비라고 생각하고 자식 찾기
+ index = which(pedi2$sire == temp[j, "animal"] & pedi2[which(pedi2$sire == temp[j, "animal"]), "flag"] == 0)
+ progeny = as.data.frame(pedi2[index, "animal"])
+ names(progeny) = names(temp)
+ temp = rbind(temp, progeny)
+
+ # 어미라고 생각하고 자식 찾기
+ index = which(pedi2$dam == temp[j, "animal"] & pedi2[which(pedi2$dam == temp[j, "animal"]), "flag"] == 0)
+ progeny = as.data.frame(pedi2[index, "animal"])
+ names(progeny) = names(temp)
+ temp = rbind(temp, progeny)
+
+ # 1000개마다 처리 중임을 표시
+ if( (j %% 1000) == 1 ){
+ print(paste("Group " , group_num , ": ", j, " processing"))
+ }
+
+ }
+ j = j + 1
+ }
+ }
+ }
[1] "Group 1 : 1 processing"
[1] "Group 2 : 1 processing"
[1] "Group 3 : 1 processing"
>
> pedi2 = pedi2[order(pedi2$group), ]
> pedi2
animal sire dam flag group
1 a1 0 0 1 1
2 a2 0 0 1 1
3 a3 0 0 1 1
4 a4 0 0 1 1
9 a5 a1 a2 1 1
10 a6 a3 a4 1 1
11 a7 a5 a6 1 1
14 a8 a5 a7 1 1
5 a9 0 0 1 2
6 a10 0 0 1 2
7 a11 0 0 1 2
12 a12 a9 a10 1 2
13 a13 a12 a11 1 2
8 a14 0 0 1 3
>
실제 자료일 경우 출력을 하면 안 될 것이고, 대신 head, tail, nrow 등으로 파악해야 할 것이다. 그리고 처리 중임을 표시하는 부분도 1,000개마다 할 지, 10,000개마다 할 지 수정해야 한다.
'Animal Breeding > R for Genetic Evaluation' 카테고리의 다른 글
R을 이용한 사회적 관계 모형(Social Interaction Model)의 육종가 구하기 (0) | 2021.04.15 |
---|---|
Single-step GBLUP(ssGBLUP) (0) | 2021.01.05 |
GBLUP Model with residual polygenic effects (0) | 2020.12.29 |
SNP-BLUP Model with Polygenic Effects(unweighted analysis) (0) | 2020.12.24 |
Mixed Linear Model(GBLUP model) for Computing DGV (0) | 2020.12.21 |