seekparentf90을 이용한 친자감정과 부모 찾기는 이미 포스팅한 적이 있다.

2020.02.12 - [Animal Breeding/Genomic Selection] - SNP 유전체 자료를 이용한 아비 어미 찾기

 

SNP 유전체 자료를 이용한 아비 어미 찾기

imputation 또는 qc 과정에서, 사용하는 프로그램에 따라 친자감정 결과를 제시하거나 또는 진짜 부모라고 여겨지는 개체를 찾아 주기도 한다. 여기서는 아비, 어미를 본격적으로 찾아주는 프로그

bhpark.tistory.com

 

qcf90 또는 pregsf90 프로그램을 통해서 대부분의 SNP genotype quality control을 수행할 수 있다. 그러나 이런 프로그램들은 여러 버전의 마이크로 어레이를 동시에 이용하여 quality control을 할 수 없고, 하려 한다면 imputation을 해야 한다. imputation이 필요하다면 imputation을 해서 quality control을 하면 되나, raw data를 그대로 이용하여 친자감정을 하거나 부모를 찾으려 하는 경우도 있다. seekparentf90은 약간(?)의 자료 가공을 거쳐 imputation 하지 않고, 친자 감정하거나 부모를 찾을 수 있는 기능을 제공하고 있다.

 

먼저 BovineSNP50V2, BovineSNP50V3, Hanwoo50V1의 GenomeStudio에서 출력한 finalreport를 illumina2pregs 프로그램을 이용하여 coded하였다고 하자. 그럴 경우 각 버전의 genotype과 map file은 다음과 같다.

 

BovineSNP50V2

- genotype

 

- map file

 

BovineSNP50V3

- genotype

 

- map file

 

Hanwoo50V1

- genotype

 

- map file

 

먼저 map file을 합쳐야 한다.

 

세 개의 map file을 읽어서 seekparentf90을 위한 map file 만드는 SAS 프로그램

/*
file name : make_snpmapfile_for_seekparentf90.sas

seekparentf90 프로그램을 위한 map file 만들기

BovineSNP50V2, BovineSNP50V3, HanwooSNP50V1 map file을 하나로 합치기
*/

/* BovineSNP50V2 snp_map 파일 읽기 */
data a1 ;
    infile 'snp_map_bv2' firstobs = 2;

    informat name $37. ;
    informat bv2chrmo best32. ;
    informat bv2pos best32. ;
    informat bv2oindex best32. ;

    format name $37. ;
    format bv2chrmo best32. ;
    format bv2pos best32. ;
    format bv2oindex best32. ;

    input 
            name
            bv2chrmo
            bv2pos
            bv2oindex
    ;

    bv2index = _n_;
run;

/* BovineSNP50V3 snp_map 파일 읽기 */
data b1 ;
    infile 'snp_map_bv3' firstobs = 2;

    informat name $37. ;
    informat bv3chrmo best32. ;
    informat bv3pos best32. ;
    informat bv3oindex best32. ;

    format name $37. ;
    format bv3chrmo best32. ;
    format bv3pos best32. ;
    format bv3oindex best32. ;

    input 
            name
            bv3chrmo
            bv3pos
            bv3oindex
    ;

    bv3index = _n_;
run; 

/* HanwooSNP50V1 snp_map 파일 읽기 */
data c1 ;
    infile 'snp_map_hv1' firstobs = 2;

    informat name $37. ;
    informat hv1chrmo best32. ;
    informat hv1pos best32. ;
    informat hv1oindex best32. ;

    format name $37. ;
    format hv1chrmo best32. ;
    format hv1pos best32. ;
    format hv1oindex best32. ;

    input 
            name
            hv1chrmo
            hv1pos
            hv1oindex
    ;

    hv1index = _n_;
run;
 
/* bv2, bv3, hv1 머지하기 */
    /* sort */
proc sort data = a1;
    by name;
run;

proc sort data = b1;
    by name;
run;

proc sort data = c1;
    by name;
run;

    /* 머지하기 */
data t1;
    merge a1 b1 c1;
    by name;
run;

/* 이름은 같은데 염색체, 위치가 다른 SNP */
/* 있으면 안된다. 있다면 아마도 genome build가 칩마다 다른 것일 수도 */
data t1_e1;
    set t1;

	/* bv2와 bv3 비교 */
	if bv2chrmo ~= . and bv3chrmo ~= . and bv2chrmo ~= bv3chrmo then output;

	/* bv3와 hv1 비교 */
	if bv3chrmo ~= . and hv1chrmo ~= . and bv3chrmo ~= hv1chrmo then output;
run;

/* index, 염색체 번호, 위치 번호 정리 */
data t2;
    set t1;

    /* 없었던 SNP index는 0 */
    if bv2index = . then bv2index = 0;
    if bv3index = . then bv3index = 0;
    if hv1index = . then hv1index = 0;

    /* 각 SNP의 염색체 번호 */
    chr = bv2chrmo;
    if bv2chrmo   = . then chr = bv3chrmo;
    if bv2chrmo   = . and bv3chrmo = . then chr = hv1chrmo;

    /* 각 SNP의 위치 */
    pos = bv2pos;
    if bv2pos   = . then pos = bv3pos;
    if bv2pos   = . and bv3pos = . then pos = hv1pos;

run;

/* dataset을 열어서 확인 */
proc sort data = t2;
    by chr pos;
run;

data _null_;
    set t2;
    file 'mapfile_for_seekparentf90.txt';
    if _n_ = 1 then put "SNP_ID                                  Chr       Pos       chip1     chip2     chip3";
    put name @41 chr @51 pos @61 bv2index @71 bv3index @81 hv1index;
run;

 

결과적으로 만들어진 map file은 다음과 같다. 

 

각 genotype 파일에 chip number를 넣어야 한다.

BovineSNP50V2에 chip number 1을 넣는 awk 프로그램은 다음과 같다. insert_chip_number_bv2.awk로 저장한다.

BEGIN{
}
{
    print $1 " 1 " $2 > "kbh_bv2_02.txt"
}
END {
}

 

위 awk 프로그램을 실행하는 방법은 다음과 같다.

 

awk -f insert_chip_number_bv2.awk kbh_bv2.txt
pause

 

위 내용을 run_insert_chip_number_bv2.awk.bat에 저장하면 더블 클릭하여 실행할 수 있다.

 

결과적으로 생긴 파일은 다음과 같다.

 

 

BovineSNPV3 genotype에 chip number 2를 넣는 awk 프로그램

 

BEGIN{
}
{
    print $1 " 2 " $2 > "kbh_bv3_02.txt"
}
END {
}

 

위 소스를 insert_chip_number_bv3.awk으로 저장

 

위 awk 프로그램을 실행하는 방법

awk -f insert_chip_number_bv3.awk kbh_bv3.txt
pause

 

위 명령어를 run_insert_chip_number_bv3.awk.bat에 저장하면 더블 클릭하여 실행할 수 있다.

 

결과적으로 생긴 파일은 다음과 같다. 

 

HanwooSNPV1 genotype에 chip number 3을 넣는 awk 프로그램

 

BEGIN{
}
{
    print $1 " 3 " $2 > "kbh_hv1_02.txt"
}
END {
}

 

위 소스를 insert_chip_number_hv1.awk으로 저장

 

위 awk 프로그램을 실행하는 방법

awk -f insert_chip_number_hv1.awk kbh_hv1.txt
pause

 

위 명령어를 run_insert_chip_number_hv1.awk.bat에 저장하면 더블 클릭하여 실행할 수 있다.

 

결과적으로 생긴 파일은 다음과 같다.

 

 

위 세 genotype 파일을 하나로 합치는 명령어

cat kbh_bv2_02.txt kbh_bv3_02.txt kbh_hv1_02.txt > kbh_genotype.txt
pause

 

위 명령어를 make_one_genotype_file.bat으로 저장하면 더블 클릭하여 실행할 수 있다.

 

결과적으로 생긴 파일은 다음과 같다.

 

 

친자감정을 하는 것이므로 개체의 아비와 어미가 누구인지를 나타내는 혈통파일이 있어야 한다. 준비한 혈통 파일은 다음과 같다(kbh_pedigree_yob.txt)

 

이제 seekparentf90으로 친자감정을 하고, 친자감정 불일치일 경우 아비 또는 어미를 찾아 보자.

 

seekparentf90을 실행하는 명령어는 다음과 같다.

seekparentf90 --pedfile kbh_pedigree_yob.txt --snpfile kbh_genotype.txt --chips mapfile_for_seekparentf90.txt --yob --seeksire_in_ped --seekdam_in_ped --exclude_chr 30 31 32 33 --seektype 1 --duplicate --full_log_checks | tee seekparentf90_01.log
pause

 

위 명령어를 run_seekparentf90.bat으로 저장하면 더블클릭으로 실행할 수 있다.

 

명령어 설명

 

seekparentf90 명령어

--pedfile kbh_pedigree_yob.txt 혈통 파일. 혈통 파일은 header 없음.

--snpfile kbh_genotype.txt 위에서 준비한 genotype 파일

--chips mapfile_for_seekparentf90.txt 위에서 준비한 map file

--yob 혈통의 넷째 컬럼에 출생연도가 있음

--seeksire_in_ped 혈통에서 아비 찾기

--seekdam_in_ped 혈통에서 어미 찾기

--exclude_chr 30 31 32 33 30에서 33번 염색체는 제외

--seektype 1 불일치인 경우만 아비 및 어미 찾기

--duplicate 유전자형이 중복인 개체들이 있는지 검사

--full_log_checks 많은 로그 기록

| tee seekparentf90_01.log 화면에 프린트되는 것을 파일에도 기록

 

로그는 다음과 같다.

  ---------------------------------------------------- 
 |                  SeekParentf90                     |
 |              Parent-Offspring tests                |
 |            and detection of paternity              |
 |               based on SNP markers                 |
 |                                                    |
 |                2013 - Version 1.47                 |
 |           (Last update:  Dec 15, 2022)             |
 |                                                    |
 |                                                    |
 |             INIA Las Brujas, Uruguay               |
 |        University of Georgia, Athens, US           |
  ---------------------------------------------------- 

 Options
    --pedfile kbh_pedigree_yob.txt
    --snpfile kbh_genotype.txt
    --yob
    --seeksire_in_ped
    --seekdam_in_ped
    --seektype 1
    --chips mapfile_for_seekparentf90.txt
    --exclude_chr 30 31 32 33
    --full_log_checks

 Using Jenkins hash function

 Maximum length for alphanumeric fields: 20

 Fields to read:  animal, sire, dam, yob (4)

 Elapsed time for reading and hash: .250

 Pedigree file "kbh_pedigree_yob.txt": 12412 records

 Total number of animals in pedigre: 12412
 
 Statistics for Year of Birth
  Minimun:         1990
  Maximun:         2023

 Read multiple Chip SNP file: "kbh_genotype.txt"

 Number of SNP from snp_info file: 60961

 ***** WARNING *****  Number of duplicate SNP by chr_pos: 93
 ***** List of duplicate SNP: "duplicate_snp_chr_pos"

 Exclude Chr(s)
   Chr:  30  1190
   Chr:  31    11
   Chr:  32    13
   Chr:  33   775

 Chip identification
   Chip   1: CHIP1
   Chip   2: CHIP2
   Chip   3: CHIP3
 

 Number of SNP by Chip
   Chip   1:    54609   50908   47514
   Chip   2:        0   53218   49760
   Chip   3:        0       0   53866
 
 Exclude SNP: 1989
 Maximum Available SNP for calculations: 58972
 

 Number of effective SNP by Chip for parent-progeny conflicts
   Chip   1:    52886   49233   46109
   Chip   2:        0   51278   48090
   Chip   3:        0       0   52195
    Column position in file for the first marker: 19
    Format to read SNP file: (18x,800000i1)                                                                                      
    Number of SNPs: 60961

 Threshold for exclusions - Maximun number of SNP: 58972
 Number of SNP > 130, set the threshold probability to exclude= 1.000
 Number of SNP > 130, set the threshold probability to assign = .500
 Threshold based on percent of conflicts to exclude: 1.000
 Threshold based on percent of conflicts to assign: .500

 Number of records in SNP file: 1884
 Number of records present in pedigree: 1883 1883

 Number of records by Chip
    Chip 1: 21
    Chip 2: 252
    Chip 3: 1611

 Call Rate
   Min CR:   5346 .90
   Max CR:     42 1.00
   AVG CR:    668 .99
   Number of samples with low call rate (  0.90 ):      0
 
 Samples with low call rate for effective SNP           0

 Check all pedigree for parent-progeny conflicts

 Pedigree records with genotype: 1883

 Records not tested (low call rate <  0.90 ): 0

 Records tested: 1883
 
 Pair parent/progeny tested: 1403
 Pair with conflicts: 19   1.4 %
   NOT tested (parent low call rate): 0
 
     Sire-progeny tested: 715
     Sire-progeny with conflicts: 11   1.5 %
       NOT tested (parent low call rate): 0
 
     Dam-progeny tested: 688
     Dam-progeny with conflicts: 8   1.2 %
       NOT tested (parent low call rate): 0

 Seek parent for SIRES
   Get list of parents: detected from pedigree        
     Number of Sires: 171

   Seek method: Only for animals with conflicts    

   Total number of animals: 11
      Found: 7
      Not Found: 4
      Found but cannot assign: 0

 Seek parent for DAMS
   Get list of parents: detected from pedigree        
     Number of Dams : 666

   Seek method: Only for animals with conflicts    

   Total number of animals: 8
      Found: 3
      Not Found: 5
      Found but cannot assign: 0

 Output files
     Pedigree file with removed parents for animals with conflicts: "Check_kbh_pedigree_yob.txt"

 Full reports
     "Parent_Progeny_Conflicts.txt"
     "Parent_Progeny_Conflicts_Summary.txt"
     "Seek_Sire.txt"
     "Seek_Dam.txt"
 

 

중간에

 

***** WARNING ***** Number of duplicate SNP by chr_pos: 93

***** List of duplicate SNP: "duplicate_snp_chr_pos“

 

로그가 있는데 duplicate_snp_chr_pos 파일을 열어 보면 다음과 같다,

 
Duplicate SNP chr_pos: 1_59409838 2
Duplicate SNP chr_pos: 13_25606469 2
Duplicate SNP chr_pos: 3_58040470 2
Duplicate SNP chr_pos: 14_27271835 2
Duplicate SNP chr_pos: 29_28647816 2
Duplicate SNP chr_pos: 15_15014275 2
Duplicate SNP chr_pos: 2_50689222 2
Duplicate SNP chr_pos: 11_33265117 2
Duplicate SNP chr_pos: 7_1071389 2
Duplicate SNP chr_pos: 15_79531511 2
Duplicate SNP chr_pos: 9_45729853 2
Duplicate SNP chr_pos: 25_10359385 2
Duplicate SNP chr_pos: 22_56526462 2
Duplicate SNP chr_pos: 20_676757 2
Duplicate SNP chr_pos: 22_8308367 2
Duplicate SNP chr_pos: 20_17837675 2
Duplicate SNP chr_pos: 14_56761589 2
Duplicate SNP chr_pos: 3_76797698 2
Duplicate SNP chr_pos: 25_26191380 2
Duplicate SNP chr_pos: 19_43264699 2
Duplicate SNP chr_pos: 21_65198296 2
Duplicate SNP chr_pos: 8_106174871 2
Duplicate SNP chr_pos: 15_15367990 2
Duplicate SNP chr_pos: 2_111155237 2
Duplicate SNP chr_pos: 14_76524093 2
Duplicate SNP chr_pos: 13_71212300 2
Duplicate SNP chr_pos: 14_25401722 2
Duplicate SNP chr_pos: 12_80629629 2
Duplicate SNP chr_pos: 10_49791638 2
Duplicate SNP chr_pos: 6_54524018 2
Duplicate SNP chr_pos: 3_40654331 2
Duplicate SNP chr_pos: 15_15595454 2
Duplicate SNP chr_pos: 7_21298998 2
Duplicate SNP chr_pos: 15_15738972 2
Duplicate SNP chr_pos: 7_18454636 2
Duplicate SNP chr_pos: 7_80042191 2
Duplicate SNP chr_pos: 26_38233337 2
Duplicate SNP chr_pos: 28_35331560 2
Duplicate SNP chr_pos: 15_77675440 2
Duplicate SNP chr_pos: 15_15908105 2
Duplicate SNP chr_pos: 26_8221270 2
Duplicate SNP chr_pos: 18_1839733 2
Duplicate SNP chr_pos: 15_15697628 2
Duplicate SNP chr_pos: 11_1703612 2
Duplicate SNP chr_pos: 15_21207529 2
Duplicate SNP chr_pos: 15_79187295 2
Duplicate SNP chr_pos: 22_31841994 2
Duplicate SNP chr_pos: 20_51449833 2
Duplicate SNP chr_pos: 15_15544958 2
Duplicate SNP chr_pos: 15_15520367 2
Duplicate SNP chr_pos: 15_15656347 2
Duplicate SNP chr_pos: 15_15305071 2
Duplicate SNP chr_pos: 6_61079420 2
Duplicate SNP chr_pos: 15_15213319 2
Duplicate SNP chr_pos: 16_38116988 2
Duplicate SNP chr_pos: 28_44261945 2
Duplicate SNP chr_pos: 9_10783460 2
Duplicate SNP chr_pos: 14_48380429 2
Duplicate SNP chr_pos: 29_13695183 2
Duplicate SNP chr_pos: 1_136603695 2
Duplicate SNP chr_pos: 15_15162470 2
Duplicate SNP chr_pos: 15_15245842 2
Duplicate SNP chr_pos: 3_116448759 2
Duplicate SNP chr_pos: 15_38078775 2
Duplicate SNP chr_pos: 15_15190242 2
Duplicate SNP chr_pos: 8_95410507 2
Duplicate SNP chr_pos: 3_91910014 2
Duplicate SNP chr_pos: 17_60069612 2
Duplicate SNP chr_pos: 9_98483346 2
Duplicate SNP chr_pos: 12_79289169 2
Duplicate SNP chr_pos: 1_151349514 2
Duplicate SNP chr_pos: 4_17200594 2
Duplicate SNP chr_pos: 19_47734925 2
Duplicate SNP chr_pos: 26_47781927 2
Duplicate SNP chr_pos: 8_88974063 2
Duplicate SNP chr_pos: 14_29987025 2
Duplicate SNP chr_pos: 14_31322421 2
Duplicate SNP chr_pos: 14_21343649 2
Duplicate SNP chr_pos: 1_1277227 2
Duplicate SNP chr_pos: 24_4118163 2
Duplicate SNP chr_pos: 13_49053256 2
Duplicate SNP chr_pos: 10_55611885 2
Duplicate SNP chr_pos: 28_8508619 2
Duplicate SNP chr_pos: 6_55756520 2
Duplicate SNP chr_pos: 15_15949175 2
Duplicate SNP chr_pos: 4_94176209 2
Duplicate SNP chr_pos: 14_23893220 2
Duplicate SNP chr_pos: 25_26198573 2
Duplicate SNP chr_pos: 16_33671664 2
Duplicate SNP chr_pos: 3_71860062 2
Duplicate SNP chr_pos: 5_63150400 2
Duplicate SNP chr_pos: 7_37537822 2
Duplicate SNP chr_pos: 9_32549297 2

 

93개의 염색체 번호와 위치에서 염색체 번호와 위치는 같은데 서로 다른 SNP 이름을 갖고 있다는 에러를 뿌려줌. 유전체 선발에서는 제외를 하겠지만 여기서는 제외를 해야 올바른 것인지 잘 모르겠다. 분석에서 93쌍 즉 186개 SNP를 이용했는지 안 했는지 모르겠다.

 

Pair parent/progeny tested: 1403

Pair with conflicts: 19 1.4 %

 

1403개 부모/자식을 테스트해서 19개 관계가 친자감정 불일치

 

Sire-progeny tested: 715

Sire-progeny with conflicts: 11 1.5 %

 

715개 아비/자식을 테스트해서 11개 관계가 불일치

 

Dam-progeny tested: 688

Dam-progeny with conflicts: 8 1.2 %

 

688개 어미/자식을 테스트해서 8개 관계가 불일치

 

parent_progeny_conflicts.txt

 

개체와 부모의 친자감정 결과를 보여준다. 그러나 너무 자세해서 보기 어렵다.

 

정렬을 해서 animal-dam 그리고 animal-sire 부분을 엑셀로 복사하고, D열을 내림차순 정렬하면 친자감정 불일치 개체 19두를 찾을 수 있다.

 

친자감정 불일치가 일어나는 경우는 세 가지이다. 1) 부(모)의 유전자형이 잘못 되었다. 2) 자손의 유전자형이 잘못되었다. 3) 혈통이 잘못되었다.

 

친자감정 불일치가 일어날 경우 1)과 2)를 생각안하고 무턱대고 3)을 생각할 경우 심각한 문제를 초래할 수 있다. 그러면 유전자형이 정말 제대로 되었는지는 어떻게 알 수 있는가?

 

parent_progeny_conflicts_summary.txt를 보자.

 

KOR002085189555 개체의 경우는 아비로서 9번 친자감정을 했고 그중 1번만 불일치다. 그러면 8번은 맞은 경우이므로 자기 자신의 유전자형이라고 확신할 수 있다.

 

그러나 KOR002072558437 는 개체로서 2번 친자감정 되었는데 2번다 친자감정 불일치가 났다. 이런 경우 자신의 유전자형이라고 보기 매우 힘들다. (아니라는 확신은 못한다.) 다시 genotyping을 할 수 있다면 하고, 다른 친자감정 결과 예를 들어 Microsatellite 친자감정 결과가 있다면 참고하여 결정하여야 한다.

 

조직을 샘플링할 때, 실험할 때, 결과를 처리할 때 등등 자신의 유전자형이 아닐 확률은 너무나 많다. 위와 같이 친자감정 일치가 하나라도 나왔다면 자신의 유전자형이라고 확신할 수 있지만 친자감정 일치가 없다면 자신의 유전자형인지 강한 의심을 하고, 그다음으로 혈통을 고민해야 한다.

 

A라는 개체가 B의 유전자형을 들고 우수한 개체로 판명이 나고, 그 결과를 이용하여 부모로 자손을 생산한다면 얼마나 큰 실수인가.

아래는 자신의 유전자형을 확신할 때 보는 부분이다. 즉 자신의 유전자형이 맞으므로 혈통을 수정해야 할 경우 보는 부분이다.

 

Seek method: Only for animals with conflicts

 

Total number of animals: 11

Found: 7

Not Found: 4

Found but cannot assign: 0

 

아비 불일치 11개 중 7개를 찾았다.

 

Seek method: Only for animals with conflicts

 

Total number of animals: 8

Found: 3

Not Found: 5

 

어미 불일치 8개 중 3개를 찾고, 5개는 찾지 못했다.

 

Output files

Pedigree file with removed parents for animals with conflicts: "Check_kbh_pedigree_yob.txt“

 

불일치인 개체의 부 또는 모 정보를 제거한 혈통 파일

 

아비 찾기 결과 seek_sire.txt

 

 

위에선 7개의 아비를 찾았다고 했으나 8개를 찾은 결과가 나옴. 이건 뭐지?

 

seek_dam.txt

 

 

3개의 어미를 찾았다.

SNP 정보를 기반으로 아비와 어미를 찾아주었다고 하여 무조건 믿는 것도 안된다. 같은 농장인지, 같은 농장이 아니라면 인공수정이나 수정란 이식인지, 부모의 나이가 많은지 등등을 종합적으로 살펴보고 수정하여야 한다.
 

이렇게 자기 자신의 올바른 유전자형과 올바른 혈통이 있다면 imputation 정확도가 매우 높아진다. 

 

요약

1) 파일 준비
 * genotype file
  - kbh_bv2.txt
  - kbh_bv3.txt
  - kbh_hv1.txt
 
 * chip 번호 넣는 awk 파일과 awk을 실행시키는 batch 파일
  - insert_chip_number_bv2.awk, run_insert_chip_number_bv2.awk.bat
  - insert_chip_number_bv3.awk, run_insert_chip_number_bv3.awk.bat
  - insert_chip_number_hv1.awk, run_insert_chip_number_hv1.awk.bat

 * chip 번호 넣은 genotype file을 합치는 파일
  - make_one_genotype_file.bat

 * map file
  - snp_map_bv2
  - snp_map_bv3
  - snp_map_hv1
  
 * 통합 map file을 만드는 SAS 프로그램
  - make_snpmapfile_for_seekparentf90.sas 

 * 혈통 파일
  - kbh_pedigree_yob.txt
  
 * seekparentf90 실행 파일
  - run_seekparentf90.bat

2) 실행
 * genotyp file 준비
  - run_insert_chip_number_bv2.awk.bat
  - run_insert_chip_number_bv3.awk.bat
  - run_insert_chip_number_hv1.awk.bat
  - make_one_genotype_file.bat
  
  * map file 준비
   - make_snpmapfile_for_seekparentf90.sas (새로운 칩이 추가 되지 않는다면 기존 결과(mapfile_for_seekparentf90.txt) 사용 가능)
   
  *  seekparentf90 실행
   - run_seekparentf90.bat
   

seekparentf90_for_multiple_chips.zip
0.00MB

# Social Interaction Model
# Linear Models for the Prediction of Animal Breeding Values, 3rd Edition.
# Raphael Mrode
# Example 8.1 p125

# Introduction to BLUPF90 suite programs
# Standard Edition
# Yutaka Masuda
# University of Georgia
# September 2019

참고

2021.04.15 - [Animal Breeding/R for Genetic Evaluation] - R을 이용한 사회적 관계 모형(Social Interaction Model)의 육종가 구하기

 

R을 이용한 사회적 관계 모형(Social Interaction Model)의 육종가 구하기

# Social Interaction Model # Linear Models for the Prediction of Animal Breeding Values, 3rd Edition. # Raphael Mrode # Example 8.1 p125 하나의 펜(pen) 또는 케이지에 여러 마리를 검정할..

bhpark.tistory.com

 

자료

7 1 4 1 1 5.5 8 9 1
8 1 4 1 2 9.8 7 9 1
9 2 5 1 2 4.9 7 8 2
10 1 4 2 1 8.23 11 12 1
11 2 5 2 2 7.5 10 12 2
12 3 6 2 2 10 10 11 3
13 2 5 3 1 4.5 14 15 2
14 3 6 3 2 8.4 13 15 3
15 3 6 3 1 6.4 13 14 3

1열 : animal

2열 : sire

3열 : dam

4열 : pen

5열 : sex

6열 : 성장율

7 - 8열 : 같은 펜에 있는 동기축 개체

9열 : fullsib 효과

 

주어지는 자료는 6열까지이다. fullsib 효과야 2열과 3열을 붙이면 되는 거니까 어렵지 않다. 문제는 동기축을 자료로 붙이는 일이다. 그리고 리넘된 자료로 해야 하므로 renumf90을 적당히 돌리고, 같은 펜에 있는 동기축의 renumber된 번호를 붙여야 한다. 여기서는 일단 수동으로 자료를 준비하여 분석한다.

혈통

1 0 0
2 0 0
3 0 0
4 0 0
5 0 0
6 0 0
7 1 4
8 1 4
9 2 5
10 1 4
11 2 5
12 3 6
13 2 5
14 3 6
15 3 6

 

blupf90 파라미터 파일

DATAFILE
social2_data.txt
NUMBER_OF_TRAITS
1
NUMBER_OF_EFFECTS
6
OBSERVATION(S)
6
WEIGHT(S)

EFFECTS:
 5 2 cross # sex
 1 15 cross # direct genetic
 7 0 cross # associative genetic 1
 8 15 cross # associative genetic 2
 9 3 cross # common environmental
 4 3 cross # random group (pen)
RANDOM_RESIDUAL VALUES
48.48
RANDOM_GROUP
2 3
RANDOM_TYPE
add_animal
FILE
social_pedi.txt
(CO)VARIANCES
25.7 2.25
2.25 3.60
RANDOM_GROUP
5
RANDOM_TYPE
diagonal
FILE

(CO)VARIANCES
12.5
RANDOM_GROUP
6
RANDOM_TYPE
diagonal
FILE

(CO)VARIANCES
12.12
OPTION solv_method FSPAK

 

보통의 유전평가는 renumf90 프로그램으로 renumber를 하고, renumf90이 만들어낸 파라미터 파일을 약간 수정하여 분석하지만 여기서는 renumer되었으므로 blupf90용 파라미터 파일을 이용한다.

파라미터 파일이 약간 tricky하다.

EFFECTS:
 5 2 cross # sex
 1 15 cross # direct genetic
 7 0 cross # associative genetic 1
 8 15 cross # associative genetic 2

sex 효과, direct genetic 효과는 일반적이다. 그러나 associative genetic 효과의 design matrix는 일반적인 design matrix와는 다르다. 일반적인 design matrix는 한 행에 1이 하나만 들어가나, associative genetic 효과의 design matrix는 한 행에 같은  pen(group)에 있는 동기축들을 1로 해야 한다. 그래서 7열은 레벨을 만들지 말고, 8열로만 레벨을 만들어 한 효과로 처리하고 동기축을 1로 한다는 의미이다.

 

실행화면

blupf90 blupf90_social.par | tee blupf90_social_01.log

 

로그

blupf90_social.par
     BLUPF90 ver. 1.68

 Parameter file:             blupf90_social.par
 Data file:                  social2_data.txt
 Number of Traits             1
 Number of Effects            6
 Position of Observations      6
 Position of Weight (1)        0
 Value of Missing Trait/Observation           0

EFFECTS
 #  type                position (2)        levels   [positions for nested]
    1  cross-classified       5         2
    2  cross-classified       1        15
    3  cross-classified       7         0
    4  cross-classified       8        15
    5  cross-classified       9         3
    6  cross-classified       4         3

 Residual (co)variance Matrix
  48.480    

 correlated random effects     2  3
 Type of Random Effect:      additive animal
 Pedigree File:              social_pedi.txt                                                                                                                                                                                                                                           
 trait   effect    (CO)VARIANCES
  1       2     25.70       2.250    
  1       3     2.250       3.600    

 Random Effect(s)    5
 Type of Random Effect:      diagonal
 trait   effect    (CO)VARIANCES
  1       5     12.50    

 Random Effect(s)    6
 Type of Random Effect:      diagonal
 trait   effect    (CO)VARIANCES
  1       6     12.12    

 REMARKS
  (1) Weight position 0 means no weights utilized
  (2) Effect positions of 0 for some effects and traits means that such
      effects are missing for specified traits
 

 * The limited number of OpenMP threads = 4

 * solving method (default=PCG):FSPAK               
 
 Data record length =            9
 # equations =           38
 G
  25.700      2.2500    
  2.2500      3.6000    
 G
  12.500    
 G
  12.120    
 read            9  records in   0.1406250      s,                     139 
  nonzeroes
  read           15  additive pedigrees
 finished peds in   0.1406250      s,                     250  nonzeroes
 solutions stored in file: "solutions"

 

solutions

trait/effect level  solution
   1   1         1          6.00414149
   1   1         2          8.24268672
   1   2         1          0.29558614
   1   2         2         -0.48338296
   1   2         3          0.18779681
   1   2         4          0.29558614
   1   2         5         -0.48338296
   1   2         6          0.18779681
   1   2         7          0.12478232
   1   2         8          0.52180202
   1   2         9         -0.87358211
   1   2        10          0.53576023
   1   2        11         -0.48764109
   1   2        12          0.39919156
   1   2        13         -0.57230863
   1   2        14          0.15302685
   1   2        15          0.19896884
   1   4         1         -0.04446498
   1   4         2          0.02782802
   1   4         3          0.01663697
   1   4         4         -0.04446498
   1   4         5          0.02782802
   1   4         6          0.01663697
   1   4         7         -0.07597626
   1   4         8         -0.09883240
   1   4         9          0.00894718
   1   4        10         -0.00305127
   1   4        11          0.08331352
   1   4        12          0.05970749
   1   4        13          0.01905137
   1   4        14          0.00474261
   1   4        15          0.00209776
   1   5         1          0.33277773
   1   5         2         -0.51533364
   1   5         3          0.18255591
   1   6         1         -0.26871653
   1   6         2          0.35903349
   1   6         3         -0.09031696

 

그러나 리넘버된 개체의 동기축(same pen or same group)을 옆에 추가한다는 것이 쉽지는 않은 일이다. 그래서 다음과 같은 자료에서 renumf90 과 R을 이용해서 자료를 준비해 본다.

자료

a7 a1 a4 1 1 5.5
a8 a1 a4 1 2 9.8
a9 a2 a5 1 2 4.9
a10 a1 a4 2 1 8.23
a11 a2 a5 2 2 7.5
a12 a3 a6 2 2 10
a13 a2 a5 3 1 4.5
a14 a3 a6 3 2 8.4
a15 a3 a6 3 1 6.4

animal, sire, dam, sex, growth

 

혈통

a1 0 0
a2 0 0
a3 0 0
a4 0 0
a5 0 0
a6 0 0
a7 a1 a4
a8 a1 a4
a9 a2 a5
a10 a1 a4
a11 a2 a5
a12 a3 a6
a13 a2 a5
a14 a3 a6
a15 a3 a6

 

renumf90 파라미터 파일

여기서는 associative effect 는 없고, sex, animal, pen, common environment effect(full-sib) 효과만 있는 것으로 한다.

# Parameter file for program renf90; it is translated to parameter
# file for BLUPF90 family programs.
COMBINE 7 2 3
DATAFILE
social1_data.txt
TRAITS
6
FIELDS_PASSED TO OUTPUT

WEIGHT(S)

RESIDUAL_VARIANCE
48.48
EFFECT
5 cross numer
EFFECT
1 cross alpha
RANDOM
animal
FILE
social1_pedi.txt
FILE_POS
1 2 3
PED_DEPTH
0
(CO)VARIANCES
25.7
EFFECT
4 cross numer
RANDOM
diagonal
(CO)VARIANCES
12.12
EFFECT
7 cross alpha
RANDOM
diagonal
(CO)VARIANCES
12.5
OPTION sol se

 

공통 환경 효과는 2열과 3열을 combine해서 만들었다.

실행

renumf90 renumf90_social1.par

 

실행결과

renadd02.ped

1 12 15 1 0 2 1 0 0 a14
2 10 13 1 0 2 1 0 0 a8
12 0 0 3 0 0 0 3 0 a3
3 11 14 1 0 2 1 0 0 a9
13 0 0 3 0 0 0 0 3 a4
14 0 0 3 0 0 0 0 3 a5
4 12 15 1 0 2 1 0 0 a15
15 0 0 3 0 0 0 0 3 a6
5 10 13 1 0 2 1 0 0 a10
10 0 0 3 0 0 0 3 0 a1
6 11 14 1 0 2 1 0 0 a11
7 12 15 1 0 2 1 0 0 a12
8 10 13 1 0 2 1 0 0 a7
11 0 0 3 0 0 0 3 0 a2
9 11 14 1 0 2 1 0 0 a13

 

renf90.dat

 5.5 1 8 1 1
 9.8 2 2 1 1
 4.9 2 3 1 2
 8.23 1 5 2 1
 7.5 2 6 2 2
 10 2 7 2 3
 4.5 1 9 3 2
 8.4 2 1 3 3
 6.4 1 4 3 3

 

renf90.tables

 Effect group 1 of column 1 with 2 levels, effect # 1
 Value    #    consecutive number
1 4 1 
2 5 2 
 Effect group 3 of column 1 with 3 levels, effect # 3
 Value    #    consecutive number
1 3 1 
2 3 2 
3 3 3 
 Effect group 4 of column 1 with 3 levels, effect # 4
 Value    #    consecutive number
a1a4 3 1 
a2a5 3 2 
a3a6 3 3 

 

renf90.par

# BLUPF90 parameter file created by RENUMF90
DATAFILE
 renf90.dat
NUMBER_OF_TRAITS
           1
NUMBER_OF_EFFECTS
           4
OBSERVATION(S)
    1
WEIGHT(S)
 
EFFECTS: POSITIONS_IN_DATAFILE NUMBER_OF_LEVELS TYPE_OF_EFFECT[EFFECT NESTED]
 2         2 cross 
 3        15 cross 
 4         3 cross 
 5         3 cross 
RANDOM_RESIDUAL VALUES
   48.480    
 RANDOM_GROUP
     2
 RANDOM_TYPE
 add_animal   
 FILE
renadd02.ped                                                                    
(CO)VARIANCES
   25.700    
 RANDOM_GROUP
     3
 RANDOM_TYPE
 diagonal     
 FILE
                                                                                
(CO)VARIANCES
   12.120    
 RANDOM_GROUP
     4
 RANDOM_TYPE
 diagonal     
 FILE
                                                                                
(CO)VARIANCES
   12.500    
OPTION sol se

 

위의 renf90.dat와 renf90.par는 바로 사용할 수가 없다. renf90.dat를 읽어서 same pen( or same group)의 동기축을 추가하는 프로그램이 필요하다.

# Analyse the social interaction model using blupf90
# Add competitors' renum ID in the group after running renumf90

# set working directory 
setwd(".") 

# print working directory 
getwd()

# read renf90.dat after running renumf90
data_01 = read.table("renf90.dat", header = FALSE, sep = "", col.names = c("grow", "sex", "raid", "pen", "ce"))
data_01

# raid by pen
data_02 = data_01[order(data_01$pen),]
data_02

rabp_r = length(unique(data_02$pen))
rabp_r

rabp_c = max(table(data_02$pen)) + 1
rabp_c

rabp = matrix(0, rabp_r, rabp_c)
rabp

j = 1
k = 1
rabp[j, k] = rabp[j, k] = data_02$pen[1]
k = k + 1
rabp[j, k] = rabp[j, k] = data_02$raid[1]

for (i in 2 : nrow(data_02)) {
   # i = 2
    if(data_02$pen[i - 1] == data_02$pen[i]) {
        k = k + 1
        rabp[j, k] = data_02$raid[i]
    }
    else {
        j = j + 1
        k = 1
        rabp[j, k] = rabp[j, k] = data_02$pen[i]
        k = k + 1
        rabp[j, k] = rabp[j, k] = data_02$raid[i]
    }
}

rabp

# data_02에 competitor 열 추가
data_03 = data_02
for (i in 1 : (rabp_c - 2)) {
    print(i)  
    data_03 = cbind(data_03, 0)
}
data_03

# add competitors
for (i in 1 : nrow(data_03)) {
    # pen number of data
    pn = data_03$pen[i]
    
    # row number of pen number in rabp
    rn = which(rabp[,1] == pn)

    # number of columns of data_01
    nc = ncol(data_01)
    for (j in 2 : ncol(rabp)) {
        # if raid is different from competitor
        if (data_03$raid[i] != rabp[rn, j]) {
            nc = nc + 1
            data_03[i, nc] = rabp[rn, j]
        }
    }
}
data_03

write.table(data_03, "renf90_02.dat", sep=" ", row.names = FALSE, col.names = FALSE, quote = FALSE)

 

결과로 생긴 renf90_02.dat는 다음과 같다.

5.5 1 8 1 1 2 3
9.8 2 2 1 1 8 3
4.9 2 3 1 2 8 2
8.23 1 5 2 1 6 7
7.5 2 6 2 2 5 7
10 2 7 2 3 5 6
4.5 1 9 3 2 1 4
8.4 2 1 3 3 9 4
6.4 1 4 3 3 9 1

 

blupf90을 실행하기 위하여 renf90.par를 수정한다. 

# BLUPF90 parameter file created by RENUMF90
DATAFILE
 renf90_02.dat
NUMBER_OF_TRAITS
           1
NUMBER_OF_EFFECTS
           6
OBSERVATION(S)
    1
WEIGHT(S)
 
EFFECTS: POSITIONS_IN_DATAFILE NUMBER_OF_LEVELS TYPE_OF_EFFECT[EFFECT NESTED]
 2         2 cross 
 3        15 cross 
 6         0 cross # associative genetic 1
 7        15 cross # associative genetic 2
 4         3 cross 
 5         3 cross 
RANDOM_RESIDUAL VALUES
   48.480    
 RANDOM_GROUP
     2 3
 RANDOM_TYPE
 add_animal   
 FILE
renadd02.ped                                                                    
(CO)VARIANCES
25.7 2.25
2.25 3.60
 RANDOM_GROUP
     5
 RANDOM_TYPE
 diagonal     
 FILE
                                                                                
(CO)VARIANCES
   12.120    
 RANDOM_GROUP
     6
 RANDOM_TYPE
 diagonal     
 FILE
                                                                                
(CO)VARIANCES
   12.500    
OPTION sol se

 

실행 결과 solutions

trait/effect level  solution          s.e.
   1   1         1          6.00414149          5.87722318
   1   1         2          8.24268672          5.56132372
   1   2         1          0.15302685          4.57296859
   1   2         2          0.52180202          4.52043322
   1   2         3         -0.87358211          4.57571923
   1   2         4          0.19896884          4.53216874
   1   2         5          0.53576023          4.60038547
   1   2         6         -0.48764109          4.57506398
   1   2         7          0.39919156          4.55704542
   1   2         8          0.12478232          4.60557709
   1   2         9         -0.57230863          4.56574172
   1   2        10          0.29558614          4.86839186
   1   2        11         -0.48338296          4.86816815
   1   2        12          0.18779681          4.85815710
   1   2        13          0.29558614          4.86839186
   1   2        14         -0.48338296          4.86816815
   1   2        15          0.18779681          4.85815710
   1   4         1          0.00474261          1.84114013
   1   4         2         -0.09883240          1.83170549
   1   4         3          0.00894718          1.88441482
   1   4         4          0.00209776          1.83375166
   1   4         5         -0.00305127          1.86104141
   1   4         6          0.08331352          1.88132183
   1   4         7          0.05970749          1.85378900
   1   4         8         -0.07597626          1.83835336
   1   4         9          0.01905137          1.88519935
   1   4        10         -0.04446498          1.87204137
   1   4        11          0.02782802          1.89561822
   1   4        12          0.01663697          1.87131689
   1   4        13         -0.04446498          1.87204137
   1   4        14          0.02782802          1.89561822
   1   4        15          0.01663697          1.87131689
   1   5         1         -0.26871653          3.16958408
   1   5         2          0.35903349          3.07874277
   1   5         3         -0.09031696          3.19664443
   1   6         1          0.33277773          3.25808128
   1   6         2         -0.51533364          3.19778089
   1   6         3          0.18255591          3.23629084

 

renadd02.ped를 보고 original ID를 찾아볼 수 있다. 순서가 바뀌었을 뿐 결과가 이전과 같다.

# Social Interaction Model

# Linear Models for the Prediction of Animal Breeding Values, 3rd Edition.

# Raphael Mrode

# Example 8.1 p125

하나의 펜(pen) 또는 케이지에 여러 마리를 검정할 경우 개체들 사이의 경쟁과 협력에 따라서 검정 결과가 달라진다. 

 

기본적으로 주어지는 자료는 다음과 같다.

 

7 1 4 1 1 5.5
8 1 4 1 2 9.8
9 2 5 1 2 4.9
10 1 4 2 1 8.23
11 2 5 2 2 7.5
12 3 6 2 2 10
13 2 5 3 1 4.5
14 3 6 3 2 8.4
15 3 6 3 1 6.4

 

1열 : 개체

2열 : 아비

3열 : 어미

4열 : 펜

5열 : 성별

6열 : 성장율

 

그런데 같은 펜에 있는 동기축에 대한 고려가 있어야 하므로 같은 펜 내의 개체를 제외한 다른 개체를 열로 추가하여야 한다. 동기축을 열에 추가한 결과는 다음과 같다.

7 1 4 1 1 5.5 8 9
8 1 4 1 2 9.8 7 9
9 2 5 1 2 4.9 7 8
10 1 4 2 1 8.23 11 12
11 2 5 2 2 7.5 10 12
12 3 6 2 2 10 10 11
13 2 5 3 1 4.5 14 15
14 3 6 3 2 8.4 13 15
15 3 6 3 1 6.4 13 14

 

7열 : 첫째 동기축(경쟁자)

8열 : 둘째 동기축(경쟁자)

 

모형

1. 성별효과 : 고정효과

2. 직접 육종가(direct EBV)

3. 조합 육종가(associative EBV) - 표현형을 동기축에 연결

4. 그룹(pen) 효과 : 임의 효과

5. 공통 환경 효과 - full-sib  효과 : 임의 효과

등을 포함한다.

 

모수

직접 육종가와 조합육종가의 분산 : 25.7, 3.6

직접 육종가와 조합육종가 사이의 공분산 : 2.25

공통 환경 분산 : 12.5

직접 효과의 잔차 분산 : 40.6

조합 효과의 잔차 분산 : 10.0

같은 펜에 있는 개체 사이의 상관 : 0.2

 

혈통

1 0 0
2 0 0
3 0 0
4 0 0
5 0 0
6 0 0
7 1 4
8 1 4
9 2 5
10 1 4
11 2 5
12 3 6
13 2 5
14 3 6
15 3 6

 

R 프로그램

# Social interaction effect model - Date : 2021-4-14

# Linear Models for the Prediction of Animal Breeding Values, 3rd Edition
# Raphael Mrode
# Example 8.1 p125

# MASS packages 
if (!("MASS" %in% installed.packages())){
  install.packages('MASS', dependencies = TRUE)  
}
library(MASS)

# functions

# make design matrix 
desgn <- function(v) {
  if (is.numeric(v)) {
    va = v
    mrow = length(va)
    mcol = max(va)
  }
  if (is.character(v)) {
    vf = factor(v)
    # 각 수준의 인덱스 값을 저장
    va = as.numeric(vf)
    mrow = length(va)
    mcol = length(levels(vf))
  }
  
  # 0으로 채워진 X 준비
  X = matrix(data = c(0), nrow = mrow, ncol = mcol)
  
  for (i in 1:mrow) {
    ic = va[i]
    X[i, ic] = 1
  }
  return(X)
}

# function to make inverse of numerator relationship matrix
ainv = function(pedi) {
  n = nrow(pedi)
  Ainv = matrix(c(0), nrow = n, ncol = n)
  
  for (i in 1:n) {
    animal = pedi[i, 1]
    sire = pedi[i, 2]
    dam = pedi[i, 3]
    
    if (sire == 0 & dam == 0) {
      # both parents unknown
      alpha = 1
      Ainv[animal, animal] = alpha + Ainv[animal, animal]
    } else if (sire != 0 & dam == 0) {
      # sire known
      alpha = 4/3
      Ainv[animal, animal] = alpha + Ainv[animal, animal]
      Ainv[animal, sire] = -alpha/2 + Ainv[animal, sire]
      Ainv[sire, animal] = -alpha/2 + Ainv[sire, animal]
      Ainv[sire, sire] = alpha/4 + Ainv[sire, sire]
    } else if (sire == 0 & dam != 0) {
      # dam known
      alpha = 4/3
      Ainv[animal, animal] = alpha + Ainv[animal, animal]
      Ainv[animal, dam] = -alpha/2 + Ainv[animal, dam]
      Ainv[dam, animal] = -alpha/2 + Ainv[dam, animal]
      Ainv[dam, dam] = alpha/4 + Ainv[dam, dam]
    } else {
      # both parents known
      alpha = 2
      Ainv[animal, animal] = alpha + Ainv[animal, animal]
      Ainv[animal, sire] = -alpha/2 + Ainv[animal, sire]
      Ainv[sire, animal] = -alpha/2 + Ainv[sire, animal]
      Ainv[animal, dam] = -alpha/2 + Ainv[animal, dam]
      Ainv[dam, animal] = -alpha/2 + Ainv[dam, animal]
      Ainv[sire, sire] = alpha/4 + Ainv[sire, sire]
      Ainv[sire, dam] = alpha/4 + Ainv[sire, dam]
      Ainv[dam, sire] = alpha/4 + Ainv[dam, sire]
      Ainv[dam, dam] = alpha/4 + Ainv[dam, dam]
    }
  }
  return(Ainv)
}

# set working directory 
setwd(".") 

# print working directory 
getwd()

# pedigree and data

# read pedigree : animal sire dam
pedi = read.table("social_pedi.txt", header = FALSE, sep = "", col.names = c("animal", "sire", "dam"),stringsAsFactors = FALSE)
pedi = pedi[order(pedi$animal),]

# print
pedi

# read data : animal sire dam pen sex growth c1 c2
data = read.table("social_data.txt", header = FALSE, sep = "", col.names = c("animal", "sire", "dam", "pen", "sex", "growth", "c1", "c2"), stringsAsFactors = FALSE)

data

# growth, testing result
y = data[, 'growth']
y

# number of animals in the pen
nap = 3
nap

# genetic variances for direct and associative, covariance between them
G = matrix(c(25.7, 2.25, 2.25, 3.6), 2, 2)
G

# common environmental variance
sigma_c = 12.5
sigma_c

# residual variance variance for direct and associative
sigma_ed = 40.6
sigma_es = 10
sigma_ed
sigma_es

# correlation among pigs in the same pen(rho)
rho = 0.2
rho

# original residual variance
sigma_e = sigma_ed + (nap - 1) * sigma_es
sigma_e

# group variance
sigma_g = rho * sigma_e
sigma_g

# final residual variance
sigma_ef = sigma_e - sigma_g
sigma_ef

# alpha : variance component ratio of G
alpha = ginv(G) * sigma_ef
alpha

alpha1 = alpha[1,1]
alpha1

alpha2 = alpha[1,2]
alpha2

alpha3 = alpha[2,2]
alpha3

alpha4 = sigma_ef / sigma_g
alpha4

alpha5 = sigma_ef / sigma_c
alpha5

# design matrix : fixed effect
X = desgn(data[,'sex'])
X

# design matrix : direct effect
Zd = desgn(data[, 'animal'])
Zd

# design matrix : associative effect
others = data[,c("c1","c2")]
others

Zs = matrix(0, 9, 15)

for (i in 1:9) {
    Zs[i, others[i, 1]] = 1
    Zs[i, others[i, 2]] = 1
}

Zs

# design matrix : group(pen) effect
V = desgn(data[, 'pen'])
V

# number of group
no_g = ncol(V)
no_g

# design matrix : full-sib common environmental effect
ce = paste0(data[, 'sire'], '_', data[, 'dam'])
ce

W = desgn(ce)
W

# number of common environmental effects
no_ce = ncol(W)
no_ce
  

# Inverse matrix of Numerator Relationship Matrix
ai = ainv(pedi)
ai

# Left hand side
XPX  = t(X) %*% X
XPZd = t(X) %*% Zd
XPZs = t(X) %*% Zs
XPV  = t(X) %*% V
XPW  = t(X) %*% W

ZdPZd = t(Zd) %*% Zd
ZdPZs = t(Zd) %*% Zs
ZdPV  = t(Zd) %*% V
ZdPW  = t(Zd) %*% W

ZsPZs = t(Zs) %*% Zs
ZsPV  = t(Zs) %*% V
ZsPW  = t(Zs) %*% W

VPV  = t(V) %*% V
VPW  = t(V) %*% W

WPW  = t(W) %*% W

XPX
XPZd
XPZs
XPV
XPW

ZdPZd
ZdPZs
ZdPV
ZdPW

ZsPZs
ZsPV
ZsPW

VPV
VPW

WPW

LHS = rbind(
        cbind(XPX,     XPZd,                   XPZs,                  XPV,                       XPW),
        cbind(t(XPZd), ZdPZd    + ai * alpha1, ZdPZs + ai * alpha2,   ZdPV,                      ZdPW),
        cbind(t(XPZs), t(ZdPZs) + ai * alpha2, ZsPZs + ai * alpha3,   ZsPV,                      ZsPW),
        cbind(t(XPV),  t(ZdPV),                t(ZsPV),               VPV + diag(no_g) * alpha4, VPW),
        cbind(t(XPW),  t(ZdPW),                t(ZsPW),               t(VPW),                    WPW + diag(no_ce) * alpha5)
)

round(LHS,2)

# Right hand side
XPy  = t(X)  %*% y
ZdPy = t(Zd) %*% y
ZsPy = t(Zs) %*% y
VPy  = t(V)  %*% y
WPy  = t(W)  %*% y

XPy
ZdPy
ZsPy
VPy
WPy

RHS = rbind(XPy,
            ZdPy,
            ZsPy,
            VPy,
            WPy
            )

RHS

# generalized inverse of LHS
gi_LHS = ginv(LHS)
round(gi_LHS, 3)

diag(gi_LHS)

# solution
sol = gi_LHS %*% RHS

# fixed effect : sex effect
sol_f1 = sol[1:2]
sol_f1

# direct EBV
sol_dbv = sol[3:17]

# associative EBV
sol_sbv = sol [18:32]

sol_bv = cbind(sol_dbv, sol_sbv, sol_dbv + sol_sbv)
sol_bv

# random effect : group effect
sol_r1 = sol[33:35]
sol_r1

# random effect : common environmental effect
sol_r2 = sol[36:38]
sol_r2

 

RStudio 실행 화면

 

실행 결과

> # Social interaction effect model - Date : 2021-4-14
> 
> # Linear Models for the Prediction of Animal Breeding Values, 3rd Edition
> # Raphael Mrode
> # Example 8.1 p125
> 
> # MASS packages 
> if (!("MASS" %in% installed.packages())){
+   install.packages('MASS', dependencies = TRUE)  
+ }
> library(MASS)
> 
> # functions
> 
> # make design matrix 
> desgn <- function(v) {
+   if (is.numeric(v)) {
+     va = v
+     mrow = length(va)
+     mcol = max(va)
+   }
+   if (is.character(v)) {
+     vf = factor(v)
+     # 각 수준의 인덱스 값을 저장
+     va = as.numeric(vf)
+     mrow = length(va)
+     mcol = length(levels(vf))
+   }
+   
+   # 0으로 채워진 X 준비
+   X = matrix(data = c(0), nrow = mrow, ncol = mcol)
+   
+   for (i in 1:mrow) {
+     ic = va[i]
+     X[i, ic] = 1
+   }
+   return(X)
+ }
> 
> # function to make inverse of numerator relationship matrix
> ainv = function(pedi) {
+   n = nrow(pedi)
+   Ainv = matrix(c(0), nrow = n, ncol = n)
+   
+   for (i in 1:n) {
+     animal = pedi[i, 1]
+     sire = pedi[i, 2]
+     dam = pedi[i, 3]
+     
+     if (sire == 0 & dam == 0) {
+       # both parents unknown
+       alpha = 1
+       Ainv[animal, animal] = alpha + Ainv[animal, animal]
+     } else if (sire != 0 & dam == 0) {
+       # sire known
+       alpha = 4/3
+       Ainv[animal, animal] = alpha + Ainv[animal, animal]
+       Ainv[animal, sire] = -alpha/2 + Ainv[animal, sire]
+       Ainv[sire, animal] = -alpha/2 + Ainv[sire, animal]
+       Ainv[sire, sire] = alpha/4 + Ainv[sire, sire]
+     } else if (sire == 0 & dam != 0) {
+       # dam known
+       alpha = 4/3
+       Ainv[animal, animal] = alpha + Ainv[animal, animal]
+       Ainv[animal, dam] = -alpha/2 + Ainv[animal, dam]
+       Ainv[dam, animal] = -alpha/2 + Ainv[dam, animal]
+       Ainv[dam, dam] = alpha/4 + Ainv[dam, dam]
+     } else {
+       # both parents known
+       alpha = 2
+       Ainv[animal, animal] = alpha + Ainv[animal, animal]
+       Ainv[animal, sire] = -alpha/2 + Ainv[animal, sire]
+       Ainv[sire, animal] = -alpha/2 + Ainv[sire, animal]
+       Ainv[animal, dam] = -alpha/2 + Ainv[animal, dam]
+       Ainv[dam, animal] = -alpha/2 + Ainv[dam, animal]
+       Ainv[sire, sire] = alpha/4 + Ainv[sire, sire]
+       Ainv[sire, dam] = alpha/4 + Ainv[sire, dam]
+       Ainv[dam, sire] = alpha/4 + Ainv[dam, sire]
+       Ainv[dam, dam] = alpha/4 + Ainv[dam, dam]
+     }
+   }
+   return(Ainv)
+ }
> 
> # set working directory 
> setwd(".") 
> 
> # print working directory 
> getwd()
[1] "D:/users/bhpark/2021/job/공부하기/01_Linear Models for the Prediction of Animal Breeding Values_3rd_Mrode/28_social interaction model_R"
> 
> # pedigree and data
> 
> # read pedigree : animal sire dam
> pedi = read.table("social_pedi.txt", header = FALSE, sep = "", col.names = c("animal", "sire", "dam"),stringsAsFactors = FALSE)
> pedi = pedi[order(pedi$animal),]
> 
> # print
> pedi
   animal sire dam
1       1    0   0
2       2    0   0
3       3    0   0
4       4    0   0
5       5    0   0
6       6    0   0
7       7    1   4
8       8    1   4
9       9    2   5
10     10    1   4
11     11    2   5
12     12    3   6
13     13    2   5
14     14    3   6
15     15    3   6
> 
> # read data : animal sire dam pen sex growth c1 c2
> data = read.table("social_data.txt", header = FALSE, sep = "", col.names = c("animal", "sire", "dam", "pen", "sex", "growth", "c1", "c2"), stringsAsFactors = FALSE)
> 
> data
  animal sire dam pen sex growth c1 c2
1      7    1   4   1   1   5.50  8  9
2      8    1   4   1   2   9.80  7  9
3      9    2   5   1   2   4.90  7  8
4     10    1   4   2   1   8.23 11 12
5     11    2   5   2   2   7.50 10 12
6     12    3   6   2   2  10.00 10 11
7     13    2   5   3   1   4.50 14 15
8     14    3   6   3   2   8.40 13 15
9     15    3   6   3   1   6.40 13 14
> 
> # growth, testing result
> y = data[, 'growth']
> y
[1]  5.50  9.80  4.90  8.23  7.50 10.00  4.50  8.40  6.40
> 
> # number of animals in the pen
> nap = 3
> nap
[1] 3
> 
> # genetic variances for direct and associative, covariance between them
> G = matrix(c(25.7, 2.25, 2.25, 3.6), 2, 2)
> G
      [,1] [,2]
[1,] 25.70 2.25
[2,]  2.25 3.60
> 
> # common environmental variance
> sigma_c = 12.5
> sigma_c
[1] 12.5
> 
> # residual variance variance for direct and associative
> sigma_ed = 40.6
> sigma_es = 10
> sigma_ed
[1] 40.6
> sigma_es
[1] 10
> 
> # correlation among pigs in the same pen(rho)
> rho = 0.2
> rho
[1] 0.2
> 
> # original residual variance
> sigma_e = sigma_ed + (nap - 1) * sigma_es
> sigma_e
[1] 60.6
> 
> # group variance
> sigma_g = rho * sigma_e
> sigma_g
[1] 12.12
> 
> # final residual variance
> sigma_ef = sigma_e - sigma_g
> sigma_ef
[1] 48.48
> 
> # alpha : variance component ratio of G
> alpha = ginv(G) * sigma_ef
> alpha
          [,1]      [,2]
[1,]  1.995575 -1.247234
[2,] -1.247234 14.246188
> 
> alpha1 = alpha[1,1]
> alpha1
[1] 1.995575
> 
> alpha2 = alpha[1,2]
> alpha2
[1] -1.247234
> 
> alpha3 = alpha[2,2]
> alpha3
[1] 14.24619
> 
> alpha4 = sigma_ef / sigma_g
> alpha4
[1] 4
> 
> alpha5 = sigma_ef / sigma_c
> alpha5
[1] 3.8784
> 
> # design matrix : fixed effect
> X = desgn(data[,'sex'])
> X
      [,1] [,2]
 [1,]    1    0
 [2,]    0    1
 [3,]    0    1
 [4,]    1    0
 [5,]    0    1
 [6,]    0    1
 [7,]    1    0
 [8,]    0    1
 [9,]    1    0
> 
> # design matrix : direct effect
> Zd = desgn(data[, 'animal'])
> Zd
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15]
 [1,]    0    0    0    0    0    0    1    0    0     0     0     0     0     0     0
 [2,]    0    0    0    0    0    0    0    1    0     0     0     0     0     0     0
 [3,]    0    0    0    0    0    0    0    0    1     0     0     0     0     0     0
 [4,]    0    0    0    0    0    0    0    0    0     1     0     0     0     0     0
 [5,]    0    0    0    0    0    0    0    0    0     0     1     0     0     0     0
 [6,]    0    0    0    0    0    0    0    0    0     0     0     1     0     0     0
 [7,]    0    0    0    0    0    0    0    0    0     0     0     0     1     0     0
 [8,]    0    0    0    0    0    0    0    0    0     0     0     0     0     1     0
 [9,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     1
> 
> # design matrix : associative effect
> others = data[,c("c1","c2")]
> others
  c1 c2
1  8  9
2  7  9
3  7  8
4 11 12
5 10 12
6 10 11
7 14 15
8 13 15
9 13 14
> 
> Zs = matrix(0, 9, 15)
> 
> for (i in 1:9) {
+     Zs[i, others[i, 1]] = 1
+     Zs[i, others[i, 2]] = 1
+ }
> 
> Zs
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15]
 [1,]    0    0    0    0    0    0    0    1    1     0     0     0     0     0     0
 [2,]    0    0    0    0    0    0    1    0    1     0     0     0     0     0     0
 [3,]    0    0    0    0    0    0    1    1    0     0     0     0     0     0     0
 [4,]    0    0    0    0    0    0    0    0    0     0     1     1     0     0     0
 [5,]    0    0    0    0    0    0    0    0    0     1     0     1     0     0     0
 [6,]    0    0    0    0    0    0    0    0    0     1     1     0     0     0     0
 [7,]    0    0    0    0    0    0    0    0    0     0     0     0     0     1     1
 [8,]    0    0    0    0    0    0    0    0    0     0     0     0     1     0     1
 [9,]    0    0    0    0    0    0    0    0    0     0     0     0     1     1     0
> 
> # design matrix : group(pen) effect
> V = desgn(data[, 'pen'])
> V
      [,1] [,2] [,3]
 [1,]    1    0    0
 [2,]    1    0    0
 [3,]    1    0    0
 [4,]    0    1    0
 [5,]    0    1    0
 [6,]    0    1    0
 [7,]    0    0    1
 [8,]    0    0    1
 [9,]    0    0    1
> 
> # number of group
> no_g = ncol(V)
> no_g
[1] 3
> 
> # design matrix : full-sib common environmental effect
> ce = paste0(data[, 'sire'], '_', data[, 'dam'])
> ce
[1] "1_4" "1_4" "2_5" "1_4" "2_5" "3_6" "2_5" "3_6" "3_6"
> 
> W = desgn(ce)
> W
      [,1] [,2] [,3]
 [1,]    1    0    0
 [2,]    1    0    0
 [3,]    0    1    0
 [4,]    1    0    0
 [5,]    0    1    0
 [6,]    0    0    1
 [7,]    0    1    0
 [8,]    0    0    1
 [9,]    0    0    1
> 
> # number of common environmental effects
> no_ce = ncol(W)
> no_ce
[1] 3
>   
> 
> # Inverse matrix of Numerator Relationship Matrix
> ai = ainv(pedi)
> ai
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15]
 [1,]  2.5  0.0  0.0  1.5  0.0  0.0   -1   -1    0    -1     0     0     0     0     0
 [2,]  0.0  2.5  0.0  0.0  1.5  0.0    0    0   -1     0    -1     0    -1     0     0
 [3,]  0.0  0.0  2.5  0.0  0.0  1.5    0    0    0     0     0    -1     0    -1    -1
 [4,]  1.5  0.0  0.0  2.5  0.0  0.0   -1   -1    0    -1     0     0     0     0     0
 [5,]  0.0  1.5  0.0  0.0  2.5  0.0    0    0   -1     0    -1     0    -1     0     0
 [6,]  0.0  0.0  1.5  0.0  0.0  2.5    0    0    0     0     0    -1     0    -1    -1
 [7,] -1.0  0.0  0.0 -1.0  0.0  0.0    2    0    0     0     0     0     0     0     0
 [8,] -1.0  0.0  0.0 -1.0  0.0  0.0    0    2    0     0     0     0     0     0     0
 [9,]  0.0 -1.0  0.0  0.0 -1.0  0.0    0    0    2     0     0     0     0     0     0
[10,] -1.0  0.0  0.0 -1.0  0.0  0.0    0    0    0     2     0     0     0     0     0
[11,]  0.0 -1.0  0.0  0.0 -1.0  0.0    0    0    0     0     2     0     0     0     0
[12,]  0.0  0.0 -1.0  0.0  0.0 -1.0    0    0    0     0     0     2     0     0     0
[13,]  0.0 -1.0  0.0  0.0 -1.0  0.0    0    0    0     0     0     0     2     0     0
[14,]  0.0  0.0 -1.0  0.0  0.0 -1.0    0    0    0     0     0     0     0     2     0
[15,]  0.0  0.0 -1.0  0.0  0.0 -1.0    0    0    0     0     0     0     0     0     2
> 
> # Left hand side
> XPX  = t(X) %*% X
> XPZd = t(X) %*% Zd
> XPZs = t(X) %*% Zs
> XPV  = t(X) %*% V
> XPW  = t(X) %*% W
> 
> ZdPZd = t(Zd) %*% Zd
> ZdPZs = t(Zd) %*% Zs
> ZdPV  = t(Zd) %*% V
> ZdPW  = t(Zd) %*% W
> 
> ZsPZs = t(Zs) %*% Zs
> ZsPV  = t(Zs) %*% V
> ZsPW  = t(Zs) %*% W
> 
> VPV  = t(V) %*% V
> VPW  = t(V) %*% W
> 
> WPW  = t(W) %*% W
> 
> XPX
     [,1] [,2]
[1,]    4    0
[2,]    0    5
> XPZd
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15]
[1,]    0    0    0    0    0    0    1    0    0     1     0     0     1     0     1
[2,]    0    0    0    0    0    0    0    1    1     0     1     1     0     1     0
> XPZs
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15]
[1,]    0    0    0    0    0    0    0    1    1     0     1     1     1     2     1
[2,]    0    0    0    0    0    0    2    1    1     2     1     1     1     0     1
> XPV
     [,1] [,2] [,3]
[1,]    1    1    2
[2,]    2    2    1
> XPW
     [,1] [,2] [,3]
[1,]    2    1    1
[2,]    1    2    2
> 
> ZdPZd
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15]
 [1,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0
 [2,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0
 [3,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0
 [4,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0
 [5,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0
 [6,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0
 [7,]    0    0    0    0    0    0    1    0    0     0     0     0     0     0     0
 [8,]    0    0    0    0    0    0    0    1    0     0     0     0     0     0     0
 [9,]    0    0    0    0    0    0    0    0    1     0     0     0     0     0     0
[10,]    0    0    0    0    0    0    0    0    0     1     0     0     0     0     0
[11,]    0    0    0    0    0    0    0    0    0     0     1     0     0     0     0
[12,]    0    0    0    0    0    0    0    0    0     0     0     1     0     0     0
[13,]    0    0    0    0    0    0    0    0    0     0     0     0     1     0     0
[14,]    0    0    0    0    0    0    0    0    0     0     0     0     0     1     0
[15,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     1
> ZdPZs
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15]
 [1,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0
 [2,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0
 [3,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0
 [4,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0
 [5,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0
 [6,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0
 [7,]    0    0    0    0    0    0    0    1    1     0     0     0     0     0     0
 [8,]    0    0    0    0    0    0    1    0    1     0     0     0     0     0     0
 [9,]    0    0    0    0    0    0    1    1    0     0     0     0     0     0     0
[10,]    0    0    0    0    0    0    0    0    0     0     1     1     0     0     0
[11,]    0    0    0    0    0    0    0    0    0     1     0     1     0     0     0
[12,]    0    0    0    0    0    0    0    0    0     1     1     0     0     0     0
[13,]    0    0    0    0    0    0    0    0    0     0     0     0     0     1     1
[14,]    0    0    0    0    0    0    0    0    0     0     0     0     1     0     1
[15,]    0    0    0    0    0    0    0    0    0     0     0     0     1     1     0
> ZdPV
      [,1] [,2] [,3]
 [1,]    0    0    0
 [2,]    0    0    0
 [3,]    0    0    0
 [4,]    0    0    0
 [5,]    0    0    0
 [6,]    0    0    0
 [7,]    1    0    0
 [8,]    1    0    0
 [9,]    1    0    0
[10,]    0    1    0
[11,]    0    1    0
[12,]    0    1    0
[13,]    0    0    1
[14,]    0    0    1
[15,]    0    0    1
> ZdPW
      [,1] [,2] [,3]
 [1,]    0    0    0
 [2,]    0    0    0
 [3,]    0    0    0
 [4,]    0    0    0
 [5,]    0    0    0
 [6,]    0    0    0
 [7,]    1    0    0
 [8,]    1    0    0
 [9,]    0    1    0
[10,]    1    0    0
[11,]    0    1    0
[12,]    0    0    1
[13,]    0    1    0
[14,]    0    0    1
[15,]    0    0    1
> 
> ZsPZs
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15]
 [1,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0
 [2,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0
 [3,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0
 [4,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0
 [5,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0
 [6,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0
 [7,]    0    0    0    0    0    0    2    1    1     0     0     0     0     0     0
 [8,]    0    0    0    0    0    0    1    2    1     0     0     0     0     0     0
 [9,]    0    0    0    0    0    0    1    1    2     0     0     0     0     0     0
[10,]    0    0    0    0    0    0    0    0    0     2     1     1     0     0     0
[11,]    0    0    0    0    0    0    0    0    0     1     2     1     0     0     0
[12,]    0    0    0    0    0    0    0    0    0     1     1     2     0     0     0
[13,]    0    0    0    0    0    0    0    0    0     0     0     0     2     1     1
[14,]    0    0    0    0    0    0    0    0    0     0     0     0     1     2     1
[15,]    0    0    0    0    0    0    0    0    0     0     0     0     1     1     2
> ZsPV
      [,1] [,2] [,3]
 [1,]    0    0    0
 [2,]    0    0    0
 [3,]    0    0    0
 [4,]    0    0    0
 [5,]    0    0    0
 [6,]    0    0    0
 [7,]    2    0    0
 [8,]    2    0    0
 [9,]    2    0    0
[10,]    0    2    0
[11,]    0    2    0
[12,]    0    2    0
[13,]    0    0    2
[14,]    0    0    2
[15,]    0    0    2
> ZsPW
      [,1] [,2] [,3]
 [1,]    0    0    0
 [2,]    0    0    0
 [3,]    0    0    0
 [4,]    0    0    0
 [5,]    0    0    0
 [6,]    0    0    0
 [7,]    1    1    0
 [8,]    1    1    0
 [9,]    2    0    0
[10,]    0    1    1
[11,]    1    0    1
[12,]    1    1    0
[13,]    0    0    2
[14,]    0    1    1
[15,]    0    1    1
> 
> VPV
     [,1] [,2] [,3]
[1,]    3    0    0
[2,]    0    3    0
[3,]    0    0    3
> VPW
     [,1] [,2] [,3]
[1,]    2    1    0
[2,]    1    1    1
[3,]    0    1    2
> 
> WPW
     [,1] [,2] [,3]
[1,]    3    0    0
[2,]    0    3    0
[3,]    0    0    3
> 
> LHS = rbind(
+         cbind(XPX,     XPZd,                   XPZs,                  XPV,                       XPW),
+         cbind(t(XPZd), ZdPZd    + ai * alpha1, ZdPZs + ai * alpha2,   ZdPV,                      ZdPW),
+         cbind(t(XPZs), t(ZdPZs) + ai * alpha2, ZsPZs + ai * alpha3,   ZsPV,                      ZsPW),
+         cbind(t(XPV),  t(ZdPV),                t(ZsPV),               VPV + diag(no_g) * alpha4, VPW),
+         cbind(t(XPW),  t(ZdPW),                t(ZsPW),               t(VPW),                    WPW + diag(no_ce) * alpha5)
+ )
> 
> round(LHS,2)
      [,1] [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16] [,17]  [,18]  [,19]  [,20]  [,21]  [,22]  [,23]  [,24]  [,25]  [,26]  [,27]  [,28]  [,29]
 [1,]    4    0  0.00  0.00  0.00  0.00  0.00  0.00  1.00  0.00  0.00  1.00  0.00  0.00  1.00  0.00  1.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00   1.00   1.00   0.00   1.00   1.00
 [2,]    0    5  0.00  0.00  0.00  0.00  0.00  0.00  0.00  1.00  1.00  0.00  1.00  1.00  0.00  1.00  0.00   0.00   0.00   0.00   0.00   0.00   0.00   2.00   1.00   1.00   2.00   1.00   1.00
 [3,]    0    0  4.99  0.00  0.00  2.99  0.00  0.00 -2.00 -2.00  0.00 -2.00  0.00  0.00  0.00  0.00  0.00  -3.12   0.00   0.00  -1.87   0.00   0.00   1.25   1.25   0.00   1.25   0.00   0.00
 [4,]    0    0  0.00  4.99  0.00  0.00  2.99  0.00  0.00  0.00 -2.00  0.00 -2.00  0.00 -2.00  0.00  0.00   0.00  -3.12   0.00   0.00  -1.87   0.00   0.00   0.00   1.25   0.00   1.25   0.00
 [5,]    0    0  0.00  0.00  4.99  0.00  0.00  2.99  0.00  0.00  0.00  0.00  0.00 -2.00  0.00 -2.00 -2.00   0.00   0.00  -3.12   0.00   0.00  -1.87   0.00   0.00   0.00   0.00   0.00   1.25
 [6,]    0    0  2.99  0.00  0.00  4.99  0.00  0.00 -2.00 -2.00  0.00 -2.00  0.00  0.00  0.00  0.00  0.00  -1.87   0.00   0.00  -3.12   0.00   0.00   1.25   1.25   0.00   1.25   0.00   0.00
 [7,]    0    0  0.00  2.99  0.00  0.00  4.99  0.00  0.00  0.00 -2.00  0.00 -2.00  0.00 -2.00  0.00  0.00   0.00  -1.87   0.00   0.00  -3.12   0.00   0.00   0.00   1.25   0.00   1.25   0.00
 [8,]    0    0  0.00  0.00  2.99  0.00  0.00  4.99  0.00  0.00  0.00  0.00  0.00 -2.00  0.00 -2.00 -2.00   0.00   0.00  -1.87   0.00   0.00  -3.12   0.00   0.00   0.00   0.00   0.00   1.25
 [9,]    1    0 -2.00  0.00  0.00 -2.00  0.00  0.00  4.99  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00   1.25   0.00   0.00   1.25   0.00   0.00  -2.49   1.00   1.00   0.00   0.00   0.00
[10,]    0    1 -2.00  0.00  0.00 -2.00  0.00  0.00  0.00  4.99  0.00  0.00  0.00  0.00  0.00  0.00  0.00   1.25   0.00   0.00   1.25   0.00   0.00   1.00  -2.49   1.00   0.00   0.00   0.00
[11,]    0    1  0.00 -2.00  0.00  0.00 -2.00  0.00  0.00  0.00  4.99  0.00  0.00  0.00  0.00  0.00  0.00   0.00   1.25   0.00   0.00   1.25   0.00   1.00   1.00  -2.49   0.00   0.00   0.00
[12,]    1    0 -2.00  0.00  0.00 -2.00  0.00  0.00  0.00  0.00  0.00  4.99  0.00  0.00  0.00  0.00  0.00   1.25   0.00   0.00   1.25   0.00   0.00   0.00   0.00   0.00  -2.49   1.00   1.00
[13,]    0    1  0.00 -2.00  0.00  0.00 -2.00  0.00  0.00  0.00  0.00  0.00  4.99  0.00  0.00  0.00  0.00   0.00   1.25   0.00   0.00   1.25   0.00   0.00   0.00   0.00   1.00  -2.49   1.00
[14,]    0    1  0.00  0.00 -2.00  0.00  0.00 -2.00  0.00  0.00  0.00  0.00  0.00  4.99  0.00  0.00  0.00   0.00   0.00   1.25   0.00   0.00   1.25   0.00   0.00   0.00   1.00   1.00  -2.49
[15,]    1    0  0.00 -2.00  0.00  0.00 -2.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  4.99  0.00  0.00   0.00   1.25   0.00   0.00   1.25   0.00   0.00   0.00   0.00   0.00   0.00   0.00
[16,]    0    1  0.00  0.00 -2.00  0.00  0.00 -2.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  4.99  0.00   0.00   0.00   1.25   0.00   0.00   1.25   0.00   0.00   0.00   0.00   0.00   0.00
[17,]    1    0  0.00  0.00 -2.00  0.00  0.00 -2.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  4.99   0.00   0.00   1.25   0.00   0.00   1.25   0.00   0.00   0.00   0.00   0.00   0.00
[18,]    0    0 -3.12  0.00  0.00 -1.87  0.00  0.00  1.25  1.25  0.00  1.25  0.00  0.00  0.00  0.00  0.00  35.62   0.00   0.00  21.37   0.00   0.00 -14.25 -14.25   0.00 -14.25   0.00   0.00
[19,]    0    0  0.00 -3.12  0.00  0.00 -1.87  0.00  0.00  0.00  1.25  0.00  1.25  0.00  1.25  0.00  0.00   0.00  35.62   0.00   0.00  21.37   0.00   0.00   0.00 -14.25   0.00 -14.25   0.00
[20,]    0    0  0.00  0.00 -3.12  0.00  0.00 -1.87  0.00  0.00  0.00  0.00  0.00  1.25  0.00  1.25  1.25   0.00   0.00  35.62   0.00   0.00  21.37   0.00   0.00   0.00   0.00   0.00 -14.25
[21,]    0    0 -1.87  0.00  0.00 -3.12  0.00  0.00  1.25  1.25  0.00  1.25  0.00  0.00  0.00  0.00  0.00  21.37   0.00   0.00  35.62   0.00   0.00 -14.25 -14.25   0.00 -14.25   0.00   0.00
[22,]    0    0  0.00 -1.87  0.00  0.00 -3.12  0.00  0.00  0.00  1.25  0.00  1.25  0.00  1.25  0.00  0.00   0.00  21.37   0.00   0.00  35.62   0.00   0.00   0.00 -14.25   0.00 -14.25   0.00
[23,]    0    0  0.00  0.00 -1.87  0.00  0.00 -3.12  0.00  0.00  0.00  0.00  0.00  1.25  0.00  1.25  1.25   0.00   0.00  21.37   0.00   0.00  35.62   0.00   0.00   0.00   0.00   0.00 -14.25
[24,]    0    2  1.25  0.00  0.00  1.25  0.00  0.00 -2.49  1.00  1.00  0.00  0.00  0.00  0.00  0.00  0.00 -14.25   0.00   0.00 -14.25   0.00   0.00  30.49   1.00   1.00   0.00   0.00   0.00
[25,]    1    1  1.25  0.00  0.00  1.25  0.00  0.00  1.00 -2.49  1.00  0.00  0.00  0.00  0.00  0.00  0.00 -14.25   0.00   0.00 -14.25   0.00   0.00   1.00  30.49   1.00   0.00   0.00   0.00
[26,]    1    1  0.00  1.25  0.00  0.00  1.25  0.00  1.00  1.00 -2.49  0.00  0.00  0.00  0.00  0.00  0.00   0.00 -14.25   0.00   0.00 -14.25   0.00   1.00   1.00  30.49   0.00   0.00   0.00
       [,30]  [,31]  [,32] [,33] [,34] [,35] [,36] [,37] [,38]
 [1,]   1.00   2.00   1.00     1     1     2  2.00  1.00  1.00
 [2,]   1.00   0.00   1.00     2     2     1  1.00  2.00  2.00
 [3,]   0.00   0.00   0.00     0     0     0  0.00  0.00  0.00
 [4,]   1.25   0.00   0.00     0     0     0  0.00  0.00  0.00
 [5,]   0.00   1.25   1.25     0     0     0  0.00  0.00  0.00
 [6,]   0.00   0.00   0.00     0     0     0  0.00  0.00  0.00
 [7,]   1.25   0.00   0.00     0     0     0  0.00  0.00  0.00
 [8,]   0.00   1.25   1.25     0     0     0  0.00  0.00  0.00
 [9,]   0.00   0.00   0.00     1     0     0  1.00  0.00  0.00
[10,]   0.00   0.00   0.00     1     0     0  1.00  0.00  0.00
[11,]   0.00   0.00   0.00     1     0     0  0.00  1.00  0.00
[12,]   0.00   0.00   0.00     0     1     0  1.00  0.00  0.00
[13,]   0.00   0.00   0.00     0     1     0  0.00  1.00  0.00
[14,]   0.00   0.00   0.00     0     1     0  0.00  0.00  1.00
[15,]  -2.49   1.00   1.00     0     0     1  0.00  1.00  0.00
[16,]   1.00  -2.49   1.00     0     0     1  0.00  0.00  1.00
[17,]   1.00   1.00  -2.49     0     0     1  0.00  0.00  1.00
[18,]   0.00   0.00   0.00     0     0     0  0.00  0.00  0.00
[19,] -14.25   0.00   0.00     0     0     0  0.00  0.00  0.00
[20,]   0.00 -14.25 -14.25     0     0     0  0.00  0.00  0.00
[21,]   0.00   0.00   0.00     0     0     0  0.00  0.00  0.00
[22,] -14.25   0.00   0.00     0     0     0  0.00  0.00  0.00
[23,]   0.00 -14.25 -14.25     0     0     0  0.00  0.00  0.00
[24,]   0.00   0.00   0.00     2     0     0  1.00  1.00  0.00
[25,]   0.00   0.00   0.00     2     0     0  1.00  1.00  0.00
[26,]   0.00   0.00   0.00     2     0     0  2.00  0.00  0.00
 [ getOption("max.print") 에 도달했습니다 -- 12 행들을 생략합니다 ]
> 
> # Right hand side
> XPy  = t(X)  %*% y
> ZdPy = t(Zd) %*% y
> ZsPy = t(Zs) %*% y
> VPy  = t(V)  %*% y
> WPy  = t(W)  %*% y
> 
> XPy
      [,1]
[1,] 24.63
[2,] 40.60
> ZdPy
       [,1]
 [1,]  0.00
 [2,]  0.00
 [3,]  0.00
 [4,]  0.00
 [5,]  0.00
 [6,]  0.00
 [7,]  5.50
 [8,]  9.80
 [9,]  4.90
[10,]  8.23
[11,]  7.50
[12,] 10.00
[13,]  4.50
[14,]  8.40
[15,]  6.40
> ZsPy
       [,1]
 [1,]  0.00
 [2,]  0.00
 [3,]  0.00
 [4,]  0.00
 [5,]  0.00
 [6,]  0.00
 [7,] 14.70
 [8,] 10.40
 [9,] 15.30
[10,] 17.50
[11,] 18.23
[12,] 15.73
[13,] 14.80
[14,] 10.90
[15,] 12.90
> VPy
      [,1]
[1,] 20.20
[2,] 25.73
[3,] 19.30
> WPy
      [,1]
[1,] 23.53
[2,] 16.90
[3,] 24.80
> 
> RHS = rbind(XPy,
+             ZdPy,
+             ZsPy,
+             VPy,
+             WPy
+             )
> 
> RHS
       [,1]
 [1,] 24.63
 [2,] 40.60
 [3,]  0.00
 [4,]  0.00
 [5,]  0.00
 [6,]  0.00
 [7,]  0.00
 [8,]  0.00
 [9,]  5.50
[10,]  9.80
[11,]  4.90
[12,]  8.23
[13,]  7.50
[14,] 10.00
[15,]  4.50
[16,]  8.40
[17,]  6.40
[18,]  0.00
[19,]  0.00
[20,]  0.00
[21,]  0.00
[22,]  0.00
[23,]  0.00
[24,] 14.70
[25,] 10.40
[26,] 15.30
[27,] 17.50
[28,] 18.23
[29,] 15.73
[30,] 14.80
[31,] 10.90
[32,] 12.90
[33,] 20.20
[34,] 25.73
[35,] 19.30
[36,] 23.53
[37,] 16.90
[38,] 24.80
> 
> # generalized inverse of LHS
> gi_LHS = ginv(LHS)
> round(gi_LHS, 3)
        [,1]   [,2]   [,3]   [,4]   [,5]   [,6]   [,7]   [,8]   [,9]  [,10]  [,11]  [,12]  [,13]  [,14]  [,15]  [,16]  [,17]  [,18]  [,19]  [,20]  [,21]  [,22]  [,23]  [,24]  [,25]  [,26]
 [1,]  0.712  0.340 -0.129 -0.093 -0.089 -0.129 -0.093 -0.089 -0.197 -0.126 -0.107 -0.193 -0.102 -0.103 -0.163 -0.091 -0.163 -0.023 -0.033 -0.042 -0.023 -0.033 -0.042 -0.029 -0.033 -0.042
 [2,]  0.340  0.638 -0.084 -0.112 -0.115 -0.084 -0.112 -0.115 -0.091 -0.149 -0.164 -0.095 -0.167 -0.167 -0.119 -0.176 -0.119 -0.040 -0.032 -0.025 -0.040 -0.032 -0.025 -0.055 -0.052 -0.044
 [3,] -0.129 -0.084  0.489  0.020  0.022 -0.041  0.020  0.022  0.213  0.204  0.024  0.213  0.024  0.027  0.031  0.025  0.034  0.042 -0.001  0.005 -0.004 -0.001  0.005  0.016  0.017 -0.005
 [4,] -0.093 -0.112  0.020  0.489  0.022  0.020 -0.041  0.022  0.025  0.029  0.211  0.025  0.211  0.030  0.208  0.030  0.027 -0.001  0.049 -0.002 -0.001  0.002 -0.002 -0.001 -0.001  0.026
 [5,] -0.089 -0.115  0.022  0.022  0.487  0.022  0.022 -0.043  0.027  0.032  0.030  0.027  0.030  0.209  0.026  0.209  0.204  0.005 -0.001  0.043  0.005 -0.001 -0.004  0.008  0.007  0.001
 [6,] -0.129 -0.084 -0.041  0.020  0.022  0.489  0.020  0.022  0.213  0.204  0.024  0.213  0.024  0.027  0.031  0.025  0.034 -0.004 -0.001  0.005  0.042 -0.001  0.005  0.016  0.017 -0.005
 [7,] -0.093 -0.112  0.020 -0.041  0.022  0.020  0.489  0.022  0.025  0.029  0.211  0.025  0.211  0.030  0.208  0.030  0.027 -0.001  0.002 -0.002 -0.001  0.049 -0.002 -0.001 -0.001  0.026
 [8,] -0.089 -0.115  0.022  0.022 -0.043  0.022  0.022  0.487  0.027  0.032  0.030  0.027  0.030  0.209  0.026  0.209  0.204  0.005 -0.001 -0.004  0.005 -0.001  0.043  0.008  0.007  0.001
 [9,] -0.197 -0.091  0.213  0.025  0.027  0.213  0.025  0.027  0.438  0.199  0.029  0.216  0.027  0.031  0.044  0.028  0.049  0.015 -0.001  0.010  0.015 -0.001  0.010  0.034  0.009 -0.008
[10,] -0.126 -0.149  0.204  0.029  0.032  0.204  0.029  0.032  0.199  0.421  0.040  0.198  0.039  0.044  0.035  0.044  0.040  0.018 -0.002  0.007  0.018 -0.002  0.007  0.013  0.039 -0.008
[11,] -0.107 -0.164  0.024  0.211  0.030  0.024  0.211  0.030  0.029  0.040  0.432  0.027  0.211  0.044  0.200  0.044  0.033 -0.005  0.026  0.002 -0.005  0.026  0.002 -0.008 -0.009  0.049
[12,] -0.193 -0.095  0.213  0.025  0.027  0.213  0.025  0.027  0.216  0.198  0.027  0.437  0.029  0.032  0.045  0.029  0.048  0.020 -0.001  0.005  0.020 -0.001  0.005  0.018  0.020 -0.003
[13,] -0.102 -0.167  0.024  0.211  0.030  0.024  0.211  0.030  0.027  0.039  0.211  0.029  0.432  0.044  0.202  0.045  0.032  0.000  0.026 -0.003  0.000  0.026 -0.003  0.002  0.001  0.029
[14,] -0.103 -0.167  0.027  0.030  0.209  0.027  0.030  0.209  0.031  0.044  0.044  0.032  0.044  0.428  0.031  0.209  0.197  0.004 -0.002  0.021  0.004 -0.002  0.021  0.008  0.008  0.002
[15,] -0.163 -0.119  0.031  0.208  0.026  0.031  0.208  0.026  0.044  0.035  0.200  0.045  0.202  0.031  0.430  0.032  0.041  0.002  0.026 -0.005  0.002  0.026 -0.005  0.003  0.003  0.028
[16,] -0.091 -0.176  0.025  0.030  0.209  0.025  0.030  0.209  0.028  0.044  0.044  0.029  0.045  0.209  0.032  0.431  0.197  0.009 -0.002  0.015  0.009 -0.002  0.015  0.014  0.013  0.002
[17,] -0.163 -0.119  0.034  0.027  0.204  0.034  0.027  0.204  0.049  0.040  0.033  0.048  0.032  0.197  0.041  0.197  0.424  0.006 -0.002  0.019  0.006 -0.002  0.019  0.009  0.009  0.001
[18,] -0.023 -0.040  0.042 -0.001  0.005 -0.004 -0.001  0.005  0.015  0.018 -0.005  0.020  0.000  0.004  0.002  0.009  0.006  0.072  0.000  0.002 -0.002  0.000  0.002  0.034  0.034 -0.001
[19,] -0.033 -0.032 -0.001  0.049 -0.001 -0.001  0.002 -0.001 -0.001 -0.002  0.026 -0.001  0.026 -0.002  0.026 -0.002 -0.002  0.000  0.074  0.000  0.000  0.000  0.000  0.000  0.000  0.037
[20,] -0.042 -0.025  0.005 -0.002  0.043  0.005 -0.002 -0.004  0.010  0.007  0.002  0.005 -0.003  0.021 -0.005  0.015  0.019  0.002  0.000  0.072  0.002  0.000 -0.002  0.003  0.003  0.001
[21,] -0.023 -0.040 -0.004 -0.001  0.005  0.042 -0.001  0.005  0.015  0.018 -0.005  0.020  0.000  0.004  0.002  0.009  0.006 -0.002  0.000  0.002  0.072  0.000  0.002  0.034  0.034 -0.001
[22,] -0.033 -0.032 -0.001  0.002 -0.001 -0.001  0.049 -0.001 -0.001 -0.002  0.026 -0.001  0.026 -0.002  0.026 -0.002 -0.002  0.000  0.000  0.000  0.000  0.074  0.000  0.000  0.000  0.037
[23,] -0.042 -0.025  0.005 -0.002 -0.004  0.005 -0.002  0.043  0.010  0.007  0.002  0.005 -0.003  0.021 -0.005  0.015  0.019  0.002  0.000 -0.002  0.002  0.000  0.072  0.003  0.003  0.001
[24,] -0.029 -0.055  0.016 -0.001  0.008  0.016 -0.001  0.008  0.034  0.013 -0.008  0.018  0.002  0.008  0.003  0.014  0.009  0.034  0.000  0.003  0.034  0.000  0.003  0.070  0.032 -0.002
[25,] -0.033 -0.052  0.017 -0.001  0.007  0.017 -0.001  0.007  0.009  0.039 -0.009  0.020  0.001  0.008  0.003  0.013  0.009  0.034  0.000  0.003  0.034  0.000  0.003  0.032  0.069 -0.002
[26,] -0.042 -0.044 -0.005  0.026  0.001 -0.005  0.026  0.001 -0.008 -0.008  0.049 -0.003  0.029  0.002  0.028  0.002  0.001 -0.001  0.037  0.001 -0.001  0.037  0.001 -0.002 -0.002  0.073
       [,27]  [,28]  [,29]  [,30]  [,31]  [,32]  [,33]  [,34]  [,35]  [,36]  [,37]  [,38]
 [1,] -0.030 -0.043 -0.051 -0.047 -0.059 -0.055 -0.063 -0.070 -0.117 -0.118 -0.074 -0.065
 [2,] -0.054 -0.043 -0.037 -0.040 -0.030 -0.034 -0.099 -0.094 -0.056 -0.060 -0.095 -0.102
 [3,]  0.019 -0.002  0.005  0.002  0.009  0.008 -0.021 -0.002  0.022 -0.040  0.021  0.019
 [4,] -0.001  0.026 -0.002  0.026 -0.002 -0.002  0.001  0.001 -0.002  0.021 -0.044  0.023
 [5,]  0.005 -0.002  0.020 -0.005  0.017  0.017  0.020  0.001 -0.021  0.019  0.023 -0.042
 [6,]  0.019 -0.002  0.005  0.002  0.009  0.008 -0.021 -0.002  0.022 -0.040  0.021  0.019
 [7,] -0.001  0.026 -0.002  0.026 -0.002 -0.002  0.001  0.001 -0.002  0.021 -0.044  0.023
 [8,]  0.005 -0.002  0.020 -0.005  0.017  0.017  0.020  0.001 -0.021  0.019  0.023 -0.042
 [9,]  0.016  0.000  0.011  0.003  0.015  0.014 -0.041  0.008  0.033 -0.048  0.026  0.022
[10,]  0.020  0.000  0.008  0.001  0.009  0.010 -0.034  0.012  0.022 -0.059  0.030  0.029
[11,] -0.003  0.028  0.003  0.028  0.002  0.002 -0.019  0.014  0.005  0.028 -0.058  0.030
[12,]  0.041 -0.006  0.000  0.003  0.010  0.009 -0.007 -0.027  0.034 -0.052  0.027  0.025
[13,] -0.003  0.049 -0.007  0.028 -0.003 -0.002  0.015 -0.021  0.006  0.024 -0.057  0.033
[14,]  0.001 -0.006  0.043 -0.003  0.020  0.020  0.029 -0.021 -0.008  0.025  0.032 -0.057
[15,]  0.003  0.028 -0.004  0.049 -0.008 -0.009  0.008  0.010 -0.018  0.030 -0.061  0.030
[16,]  0.012  0.000  0.018 -0.008  0.035  0.010  0.028  0.015 -0.043  0.020  0.032 -0.052
[17,]  0.007  0.000  0.021 -0.007  0.014  0.040  0.021  0.010 -0.031  0.031  0.028 -0.060
[18,]  0.035  0.000  0.002  0.001  0.003  0.003 -0.008  0.001  0.007 -0.003 -0.001  0.004
[19,]  0.000  0.037  0.000  0.037  0.000  0.000  0.000  0.000  0.000 -0.001  0.003 -0.001
[20,]  0.002  0.000  0.035 -0.001  0.034  0.034  0.008 -0.001 -0.007  0.004 -0.002 -0.002
[21,]  0.035  0.000  0.002  0.001  0.003  0.003 -0.008  0.001  0.007 -0.003 -0.001  0.004
[22,]  0.000  0.037  0.000  0.037  0.000  0.000  0.000  0.000  0.000 -0.001  0.003 -0.001
[23,]  0.002  0.000  0.035 -0.001  0.034  0.034  0.008 -0.001 -0.007  0.004 -0.002 -0.002
[24,]  0.035  0.001  0.004  0.001  0.004  0.004 -0.013  0.005  0.008 -0.005 -0.001  0.006
[25,]  0.035  0.001  0.004  0.001  0.004  0.004 -0.013  0.004  0.009 -0.004 -0.001  0.006
[26,]  0.000  0.037  0.002  0.037  0.001  0.001 -0.006  0.004  0.002 -0.004  0.003  0.001
 [ getOption("max.print") 에 도달했습니다 -- 12 행들을 생략합니다 ]
> 
> diag(gi_LHS)
 [1] 0.71249489 0.63796043 0.48888695 0.48884202 0.48683355 0.48888695 0.48884202 0.48683355 0.43752765 0.42149993 0.43187307 0.43654180 0.43174939 0.42835526 0.42999170 0.43135400 0.42369129
[18] 0.07228834 0.07412064 0.07223240 0.07228834 0.07412064 0.07223240 0.06971005 0.06920679 0.07324710 0.07144132 0.07300684 0.07088560 0.07330810 0.06992155 0.06936149 0.20722490 0.19551685
[35] 0.21077837 0.21895820 0.21092827 0.21603916
> 
> # solution
> sol = gi_LHS %*% RHS
> 
> # fixed effect : sex effect
> sol_f1 = sol[1:2]
> sol_f1
[1] 6.004142 8.242687
> 
> # direct EBV
> sol_dbv = sol[3:17]
> 
> # associative EBV
> sol_sbv = sol [18:32]
> 
> sol_bv = cbind(sol_dbv, sol_sbv, sol_dbv + sol_sbv)
> sol_bv
         sol_dbv      sol_sbv            
 [1,]  0.2955862 -0.044464992  0.25112116
 [2,] -0.4833830  0.027828018 -0.45555496
 [3,]  0.1877968  0.016636974  0.20443380
 [4,]  0.2955862 -0.044464992  0.25112116
 [5,] -0.4833830  0.027828018 -0.45555496
 [6,]  0.1877968  0.016636974  0.20443380
 [7,]  0.1247823 -0.075976274  0.04880605
 [8,]  0.5218020 -0.098832417  0.42296958
 [9,] -0.8735821  0.008947170 -0.86463497
[10,]  0.5357603 -0.003051276  0.53270903
[11,] -0.4876411  0.083313528 -0.40432758
[12,]  0.3991916  0.059707501  0.45889906
[13,] -0.5723087  0.019051373 -0.55325729
[14,]  0.1530269  0.004742619  0.15776954
[15,]  0.1989688  0.002097776  0.20106659
> 
> # random effect : group effect
> sol_r1 = sol[33:35]
> sol_r1
[1] -0.26871657  0.35903353 -0.09031695
> 
> # random effect : common environmental effect
> sol_r2 = sol[36:38]
> sol_r2
[1]  0.3327777 -0.5153337  0.1825559
> 

 

결과가 책과 아주 약간 다르다. blupf90으로 샐행한 결과와 더 가깝다.

 

H 행렬 유도

H 행렬의 역행렬 유도

Deriving H matrix

Deriving Inverse of H matrix

 

single-stepGBLUP의 MME에는 H 행렬의 역행렬이 등장한다. 마치 NRM과 GRM의 적당한 결합처럼 보인다. 아니 무식해서 그렇게 생각했다. 그러나 NRM과 GRM의 적당한 결합이 아니다.

다시 GBLUP을 생각해 보자. GBLUP은 SNP genotyping한 개체들의 GRM을 만들어서 개체들의 GEBV를 추정한다. 집단의 모든 개체들의 GEBV를 추정하려면 모든 개체를 SNP genotyping 하여야 한다. 그러나 한정된 예산 때문에 또는 이미 개체들이 죽어서 genotyping을 할 수 없다. 그러면 죽은 선조까지 포함하여 전체 집단에 대해서 GBLUP을 할 수는 없는 걸까? 이런 질문에서 출발하여 일부 유전체 분석을 한 개체들의 gene content를 이용하여 유전체 분석을 하지 않은 개체(non genotyped animals)들의 gene content를 추정하여 GBLUP을 하자는 것이 ssGBLUP이고 그때 H matrix를 이용하는 것이다.

유전체 분석을 한 개체는 유전체 분석 결과를 이용하고, 유전체 분석을 안 한 개체는 유전체 분석을 한 개체로부터 gene content를 추정하여 만든 GRM이 바로 H matrix이다. 

genotyped animals가 주어졌을 때 non genotyped animals의 gene contents의 분포를 이용하는 것이므로 정규 분포의 조건부 분포에 대한 이해가 필요할 수도 있다. 키워드로 conditional normal distribution, mean vector of conditional normal distribution, covariance matrix of conditional normal distribution 등을 이용할 수 있다.

 

 

H matrix는 매우 복잡하나, H 역행렬은 매우 간단한 형태를 취하고 있다. 놀라운 자연의 법칙이고, 이걸 알아내는 과학자들도 대단하다. Simple is beautiful.

# Single-step GBLUP Model(ssGBLUP)

# Linear Models for the Prediction of Animal Breeding Values, 3rd Edition.

# Raphael Mrode

# Example 11.6 p192


간단한 설명은 아래 포스팅 참조

2021/01/05 - [Animal Breeding/R for Genetic Evaluation] - Single-step GBLUP(ssGBLUP)

 

Single-step GBLUP(ssGBLUP)

# Single-step GBLUP Model(ssGBLUP) # Linear Models for the Prediction of Animal Breeding Values, 3rd Edition. # Raphael Mrode # Example 11.6 p192 single step GBLUP(ssGBLUP)은 유전체 자..

bhpark.tistory.com

 

Data(ssgblup_data.txt)

13 0 0 1 558 9 0.001792115
14 0 0 1 722 13.4 0.001385042
15 13 4 1 300 12.7 0.003333333
16 15 2 1 73 15.4 0.01369863
17 15 5 1 52 5.9 0.019230769
18 14 6 1 87 7.7 0.011494253
19 14 9 1 64 10.2 0.015625
20 14 9 1 103 4.8 0.009708738
21 1 3 1 13 7.6 0.076923077
22 14 8 1 125 8.8 0.008

animal, sire, dam, general mean, edc, dyd fat, 1/edc

 

Pedigree(ssgblup_pedi.txt)

1 0 0
2 0 0
3 0 0
4 0 0
5 0 0
6 0 0
7 0 0
8 0 0
9 0 0
10 0 0
11 0 0
12 0 0
13 0 0
14 0 0
15 13 4
16 15 2
17 15 5
18 14 6
19 14 9
20 14 9
21 1 3
22 14 8
23 14 11
24 14 10
25 14 7
26 14 12

 

SNP genotype(ssgblup_snpgenotype.txt)

18 11010202210000000000000000000000000000000000000000
19 00110202200000000000000000000000000000000000000000
20 01100102200000000000000000000000000000000000000000
21 20000122120000000000000000000000000000000000000000
22 00011202000000000000000000000000000000000000000000
23 01100102210000000000000000000000000000000000000000
24 10001102000000000000000000000000000000000000000000
25 00011202100000000000000000000000000000000000000000
26 10110201000000000000000000000000000000000000000000

 

Renumf90 파라미터 파일(renumf90_ssgblup.par)

# Parameter file for program renf90; it is translated to parameter
# file for BLUPF90 family programs.
DATAFILE
ssgblup_data.txt
TRAITS
6
FIELDS_PASSED TO OUTPUT
 
WEIGHT(S)
 7
RESIDUAL_VARIANCE
245
EFFECT
4 cross alpha
EFFECT
1 cross alpha
RANDOM
animal
FILE
ssgblup_pedi.txt
FILE_POS
1 2 3
SNP_FILE
ssgblup_snpgenotype.txt
PED_DEPTH
0
(CO)VARIANCES
35.241
OPTION no_quality_control
OPTION AlphaBeta 0.95 0.05
OPTION tunedG 0
OPTION thrStopCorAG 0.10
OPTION solv_method FSPAK

 

Renumf90 실행

renumf90 renumf90_ssgblup.par | tee renumf90_ssgblup.log

 

Renumf90 실행 화면

 

Renumf90 로그

 RENUMF90 version 1.145
 renumf90_ssgblup.par
 datafile:ssgblup_data.txt
 traits:           6
 R
   245.0    

 Processing effect  1 of type cross     
 item_kind=alpha     

 Processing effect  2 of type cross     
 item_kind=alpha     
 pedigree file name  "ssgblup_pedi.txt"
 positions of animal, sire, dam, alternate dam, yob, and group     1     2     3     0     0     0     0
 SNP file name  "ssgblup_snpgenotype.txt"
 all pedigrees to be included
 Reading (CO)VARIANCES:           1 x           1

 Maximum size of character fields: 20

 Maximum size of record (max_string_readline): 800

 Maximum number of fields for input file (max_field_readline): 100

 Pedigree search method (ped_search): convention

 Order of pedigree animals (animal_order): default

 Order of UPG (upg_order): default

 Missing observation code (missing): 0

 hash tables for effects set up
 first 3 lines of the data file (up to 70 characters)
    13 0 0 1 558 9 0.001792115
    14 0 0 1 722 13.4 0.001385042
    15 13 4 1 300 12.7 0.003333333
 read           10  records
 table with            1  elements sorted
 added count
 Effect group            1  of column            1  with            1  levels
 table expanded from        10000  to        10000  records
 added count
 Effect group            2  of column            1  with           10  levels
 wrote statistics in file "renf90.tables"

 Basic statistics for input data  (missing value code is '0')
 Pos  Min         Max         Mean        SD                 N
   6    4.8000      15.400      9.5500      3.3890          10

 random effect with SNPs  2
 type: animal    
 file: ssgblup_snpgenotype.txt
 read SNPs           9  records
 Effect group            2  of column            1  with           14  levels

 random effect   2
 type:animal    
 opened output pedigree file "renadd02.ped"
 read           26  pedigree records
 loaded           12  parent(s) in round            0

 Pedigree checks
 
 Number of animals with records                  =           10
 Number of animals with genotypes                =            9
 Number of animals with records or genotypes     =           14
 Number of animals with genotypes and no records =            4
 Number of parents without records or genotypes  =           12
 Total number of animals                         =           26

 Wrote cross reference IDs for SNP file "ssgblup_snpgenotype.txt_XrefID"

 Wrote parameter file "renf90.par"
 Wrote renumbered data "renf90.dat" 10 records

 

Renumf90 실행 결과 생성된 파일

renadd02.ped

14 4 26 1 0 12 0 0 0 26
1 0 0 3 0 0 1 1 0 13
2 15 17 1 0 12 1 0 0 21
19 0 0 3 0 0 0 0 1 5
3 4 23 1 0 12 1 0 0 19
4 0 0 3 0 0 1 8 0 14
5 4 22 1 0 12 1 0 0 22
17 0 0 3 0 0 0 0 1 3
22 0 0 3 0 0 0 0 1 8
6 1 18 1 0 2 1 2 0 15
11 4 25 1 0 12 0 0 0 23
24 0 0 3 0 0 0 0 1 10
15 0 0 3 0 0 0 1 0 1
20 0 0 3 0 0 0 0 1 6
7 6 16 1 0 2 1 0 0 16
12 4 24 1 0 12 0 0 0 24
25 0 0 3 0 0 0 0 1 11
18 0 0 3 0 0 0 0 1 4
8 6 19 1 0 2 1 0 0 17
23 0 0 3 0 0 0 0 2 9
13 4 21 1 0 12 0 0 0 25
26 0 0 3 0 0 0 0 1 12
9 4 23 1 0 12 1 0 0 20
16 0 0 3 0 0 0 0 1 2
10 4 20 1 0 12 1 0 0 18
21 0 0 3 0 0 0 0 1 7

 

Cross Reference ID(ssgblup_snpgenotype.txt_XrefID) - genotype을 가지고 있는 개체들의 renumbered ID

10 18                                                
3 19                                                
9 20                                                
2 21                                                
5 22                                                
11 23                                                
12 24                                                
13 25                                                
14 26                                                

 

renf90.dat

 9 0.001792115 1 1
 13.4 0.001385042 1 4
 12.7 0.003333333 1 6
 15.4 0.01369863 1 7
 5.9 0.019230769 1 8
 7.7 0.011494253 1 10
 10.2 0.015625 1 3
 4.8 0.009708738 1 9
 7.6 0.076923077 1 2
 8.8 0.008 1 5

 

renf90.par

# BLUPF90 parameter file created by RENUMF90
DATAFILE
 renf90.dat
NUMBER_OF_TRAITS
           1
NUMBER_OF_EFFECTS
           2
OBSERVATION(S)
    1
WEIGHT(S)
           2
EFFECTS: POSITIONS_IN_DATAFILE NUMBER_OF_LEVELS TYPE_OF_EFFECT[EFFECT NESTED]
 3         1 cross 
 4        26 cross 
RANDOM_RESIDUAL VALUES
   245.00    
 RANDOM_GROUP
     2
 RANDOM_TYPE
 add_animal   
 FILE
renadd02.ped                                                                    
(CO)VARIANCES
   35.241    
OPTION SNP_file ssgblup_snpgenotype.txt
OPTION no_quality_control
OPTION AlphaBeta 0.95 0.05
OPTION tunedG 0
OPTION thrStopCorAG 0.10
OPTION solv_method FSPAK

본 예제의 genotype은 제대로 된 genotype이 아니다. 그래서 다음 프로그램이 정상적으로 동작하지 않는다. 그래서 no_quality_control, thrStopCorAG 등의 옵션을 넣어서 강제로 실행을 하는 것이다. 실제 분석에서는 세심한 주의를 기울여서 옵션을 주고 문제점이 있나 없나 확인을 해야 한다. 그렇지 않으면 유전체 자료를 이용하는 것이 독이 될 수도 있다.

 

중간 과정을 점검하기 위하여 H 역행렬, A 역행렬, GimA22i 등등이 필요하면 위의 "OPTION solv_method FSPAK"을 지우고 다음을 추가하여 pregsf90을 실행한다. 

OPTION saveAscii
OPTION saveHinv
OPTION saveAinv
OPTION saveHinvOrig
OPTION saveAinvOrig
OPTION saveDiagGOrig
OPTION saveGOrig
OPTION saveA22Orig
OPTION saveGimA22iOrig 

여기서는 실행하지 않는다.

실제에서는 pregsf90을 실행하여 유전체 자료의 문제점이 있는지 없는지 반드시 확인하여야 한다. pregsf90은 문제점을 찾아내고 수정하기 위한 많은 옵션을 제공하는데 반드시 의미하는 바가 무엇인지 확인하고 진행하기를 바란다. 그리고 pregsf90, blupf90은 문제가 있어도 대충 덮고 실행을 계속하게 한다. 그러나 그렇게 하지 말기를 바란다. 문제가 발견되면 문제를 일으킨 유전체 자료가 무엇인지 확인하고 분석비용이 아깝긴 하지만 넣는 것이 바람직한 것인지 아니면 버리는 것이 나은 것인지 판단을 하고 진행해야 한다. 보통 버리는 것이 정신 건강상 좋다. 유전체 자료를 넣는다고 무조건 정확도가 올라가서 개량량이 증가하는 것은 아니다. 양질의 유전체 자료를 넣을 때만 그렇게 된다. 당연한 얘기가 실제에선 무시되고 마구 분석하는 현실이 안타깝기만 하다. 모든 것이 그렇듯이 유전체 자료를 이용한 유전체 선발도 마법의 도구가 아니다.

 

blupf90 실행하기 - renumf90이 만들어낸 파라미터 파일을 이용하여 blupf90 실행

다음 명령어로 실행

blupf90 renf90.par | tee blupf90_ssgblup.log

실행 화면

 

실행 로그

renf90.par
     BLUPF90 ver. 1.68

 Parameter file:             renf90.par
 Data file:                  renf90.dat
 Number of Traits             1
 Number of Effects            2
 Position of Observations      1
 Position of Weight (1)        2
 Value of Missing Trait/Observation           0

EFFECTS
 #  type                position (2)        levels   [positions for nested]
    1  cross-classified       3         1
    2  cross-classified       4        26

 Residual (co)variance Matrix
  245.00    

 Random Effect(s)    2
 Type of Random Effect:      additive animal
 Pedigree File:              renadd02.ped                                                                                                                                                                                                                                              
 trait   effect    (CO)VARIANCES
  1       2     35.24    

 REMARKS
  (1) Weight position 0 means no weights utilized
  (2) Effect positions of 0 for some effects and traits means that such
      effects are missing for specified traits
 

 * The limited number of OpenMP threads = 4

 * solving method (default=PCG):FSPAK               
 

 Options read from parameter file for genomic
 * SNP format: BLUPF90 standard (text)
 * SNP file: ssgblup_snpgenotype.txt
 * SNP Xref file: ssgblup_snpgenotype.txt_XrefID
 * No Quality Control Checks !!!!! (default .false.):  T
 * Set the threshold to Stop the analysis if low cor(A22,G) (default 0.3):  0.1
 * Create a tuned G (default = 2): 0
 * AlphaBeta defaults alpha=0.95, beta=0.05) :  0.95  0.05
 Data record length =            4
 # equations =           27
 G
  35.241    
 read           10  records in   0.9531250      s,                      21 
  nonzeroes
  read           26  additive pedigrees
 
 *--------------------------------------------------------------*
 *                 Genomic Library: Dist Version 1.281          *
 *                                                              *
 *             Optimized OpenMP Version -  4 threads            *
 *                                                              *
 *  Modified relationship matrix (H) created for effect:   2    *
 *--------------------------------------------------------------*
 
 Read 26 animals from pedigree file: "D:\users\bhpark\2021\job\공부하기\01_Linear Models for the Prediction of Animal Breeding Values_3rd_Mrode\26_ssGBLUP_blupf90\renadd02.ped"
 Number of Genotyped Animals: 9

 Creating A22 
    Extracting subset of: 19 pedigrees from: 26 elapsed time:     0.0000
    Calculating A22 Matrix by Colleau OpenMP...elapsed time: .0000
    Numbers of threads=1 4

 Reading SNP file
    Column position in file for the first marker: 4
    Format to read SNP file: (3x,400000i1)                                     
    Number of SNPs: 50
    Format: integer genotypes (0 to 5) to double-precision array
    Number of Genotyped animals: 9
    Reading SNP file elapsed time: .00
 
 Statistics of alleles frequencies in the current population
    N:             50
    Mean:       0.074
    Min:        0.000
    Max:        0.944
    Var:        0.038
 
 
 Quality Control - Monomorphic SNPs Exist - NOT REMOVED: 40

 Genotypes missings (%):  0.000

 Calculating G Matrix 
    Dgemm MKL #threads=     1    4 Elapsed omp_get_time:     0.0000
 
 Scale by Sum(2pq). Average:   3.19135802469136     

 Detecting samples with similar genotypes
    elapsed time=     0.0
 
 Blend G as alpha*G + beta*A22: (alpha,beta)     0.950     0.050

 Frequency - Diagonal of G
    N:           9
    Mean:        1.057
    Min:         0.565
    Max:         2.648
    Range:       0.104
    Class:     20
 
  #Class       Class   Count
       1  0.5645           1
       2  0.6687           1
       3  0.7729           1
       4  0.8771           4
       5  0.9813           1
       6   1.085           0
       7   1.190           0
       8   1.294           0
       9   1.398           0
      10   1.502           0
      11   1.606           0
      12   1.711           0
      13   1.815           0
      14   1.919           0
      15   2.023           0
      16   2.127           0
      17   2.232           0
      18   2.336           0
      19   2.440           0
      20   2.544           1
      21   2.648           0
 

 Check for diagonal of genomic relationship matrix

 ** High Diagonal of genotype 4  2.65 Not Removed
 ** Low Diagonal of genotype 8  0.56 Not Removed

 Check for diagonal of genomic relationship matrix, genotypes not removed: 2

 ------------------------------
  Final Pedigree-Based Matrix 
 ------------------------------
 
 Statistic of Rel. Matrix A22
                            N      Mean       Min       Max       Var
     Diagonal               9     1.000     1.000     1.000     0.000
     Off-diagonal          72     0.201     0.000     0.500     0.013
 

 ----------------------
  Final Genomic Matrix 
 ----------------------
 
 Statistic of Genomic Matrix
                            N      Mean       Min       Max       Var
     Diagonal               9     1.057     0.565     2.648     0.377
     Off-diagonal          72    -0.116    -0.742     0.725     0.142
 

 Correlation of Genomic Inbreeding and Pedigree Inbreeding
     Variance of Y is Zero !!
     Correlation:     0.0000
 
 Diagonal elements
    Estimating Regression Coefficients G = b0 11' + b1 A + e
    Regression coefficients b0 b1 =        NaN       NaN

    Correlation diagonal elements G & A       NaN
 
 All elements - Diagonal / Off-Diagonal
    Estimating Regression Coefficients G = b0 11' + b1 A + e
    Regression coefficients b0 b1 =     -0.395     1.413

    Correlation all elements G & A     0.708
 
 Off-Diagonal
    Using 56 elements from A22 >= .02000

    Estimating Regression Coefficients G = b0 11' + b1 A + e
    Regression coefficients b0 b1 =     -0.483     1.647

    Correlation Off-Diagonal elements G & A     0.212
 
 ***********************************************************************
 * CORRELATION FOR OFF-DIAGONALS G & A22 IS LOW THAN  0.50  !!!!!  *
 * MISIDENTIFIED GENOMIC SAMPLES OR POOR QUALITY GENOMIC DATA *
 ***********************************************************************

 Creating A22-inverse 
    Inverse LAPACK MKL dpotrf/i  #threads=    1    4 Elapsed omp_get_time:     0.0000

 ----------------------
  Final A22 Inv Matrix 
 ----------------------
 
 Statistic of Inv. Rel. Matrix A22
                            N      Mean       Min       Max       Var
     Diagonal               9     1.233     1.000     1.429     0.017
     Off-diagonal          72    -0.101    -0.571     0.000     0.009
 
 
 Creating G-inverse 
    Inverse LAPACK MKL dpotrf/i  #threads=    1    4 Elapsed omp_get_time:     0.0000

 --------------------------
  Final Genomic Inv Matrix 
 --------------------------
 
 Statistic of Inv. Genomic Matrix
                            N      Mean       Min       Max       Var
     Diagonal               9     5.227     1.593    11.227     9.161
     Off-diagonal          72     0.308    -5.482     3.166     3.142
 

 Check for diagonal of Inverse Genomic - Inverse of pedigree relationship matrix


 ------------------------------
  Final G Inv - A22 Inv Matrix 
 ------------------------------
 
 Statistic of Inv. Genomic - A22 Matrix
                            N      Mean       Min       Max       Var
     Diagonal               9     3.994     0.593    10.021     8.878
     Off-diagonal          72     0.408    -5.355     3.293     3.069
 

*--------------------------------------------------*
* Setup Genomic Done !!!, elapsed time:      0.049 *
*--------------------------------------------------*

 finished peds in    1.156250      s,                     108  nonzeroes
 solutions stored in file: "solutions"

 

blupf90 실행결과 생기는 파일

sum2pq

   3.19135802469136     

solutions

trait/effect level  solution
   1   1         1          8.39032676
   1   2         1          0.00291425
   1   2         2         -0.02384446
   1   2         3          0.00746559
   1   2         4          0.00433541
   1   2         5          0.00839707
   1   2         6          0.00559388
   1   2         7          0.01313654
   1   2         8         -0.00236465
   1   2         9          0.00100295
   1   2        10         -0.00244449
   1   2        11         -0.00298365
   1   2        12         -0.00082301
   1   2        13          0.00793245
   1   2        14          0.00483534
   1   2        15         -0.01192223
   1   2        16          0.00689306
   1   2        17         -0.01192223
   1   2        18          0.00275784
   1   2        19         -0.00344106
   1   2        20         -0.00307480
   1   2        21          0.00384316
   1   2        22          0.00415291
   1   2        23          0.00206656
   1   2        24         -0.00199381
   1   2        25         -0.00343423
   1   2        26          0.00177842

 

original ID 로 정렬한 개체의 gebv

rid	oid	sol
15	1	-0.01192
16	2	0.00689
17	3	-0.01192
18	4	0.00276
19	5	-0.00344
20	6	-0.00307
21	7	0.00384
22	8	0.00415
23	9	0.00207
24	10	-0.00199
25	11	-0.00343
26	12	0.00178
1	13	0.00291
4	14	0.00434
6	15	0.00559
7	16	0.01314
8	17	-0.00236
10	18	-0.00244
3	19	0.00747
9	20	0.00100
2	21	-0.02384
5	22	0.00840
11	23	-0.00298
12	24	-0.00082
13	25	0.00793
14	26	0.00484

 

해가 책과도 다르고 blupf90 팀의 Yutaka Masuda의 해와도 다르다. 위의 참고 포스팅하고는 같다. 이유는 참고 포스팅을 보기 바란다.

 

 

+ Recent posts