育种数据分析之放飞自我分享 http://blog.sciencenet.cn/u/yijiaobai 关注:生物统计,数量遗传,混合线性模型,生物信息,R,Perl,Python,GWAS,GS相关方法,文章及代码

博文

为什么相爱的人不能在一起?

已有 480 次阅读 2019-10-24 08:06 |个人分类:农学统计|系统分类:科研笔记

一个两天的bug,终于解决了,竟然是很基础的bug,花费了我两天时间,不免感叹:为什么相爱的人不能在一起。

事情是这个样子的:

最近测试一个R包breedR的动物模型的功能,用了它的测试数据:

 1> library(breedR)
2> data("globulus")
3> ped <- globulus[,1:3]
4> str(ped)
5'data.frame':    1021 obs. of  3 variables:
6 $ self: int  69 70 71 72 73 74 75 76 77 78 ...
7 $ dad : int  0 0 0 0 0 0 0 0 0 4 ...
8 $ mum : int  64 41 56 55 22 50 67 59 49 8 ...
9> res <- remlf90(  fixed = phe_X ~ gg,genetic = list(model = 'add_animal',pedig = ped,id = 'self'),data = globulus)
10Using default initial variances given by default_initial_variance()
11See ?breedR.getOption.
12
13>
 summary(res)
14Formula: phe_X ~ 0 + gg + pedigree 
15   Data: globulus 
16  AIC  BIC logLik
17 5799 5809  -2898
18
19Parameters of special components:
20
21
22Variance components:
23         Estimated variances  S.E.
24genetic                3.397 1.595
25Residual              14.453 1.529
26
27             Estimate    S.E.
28Heritability   0.1887 0.08705


这里,Va为3.39,Ve为14.45,然后我使用asreml-r作为对比:


 1> library(asreml)
 2> head(dd)
 3  self dad mum gen gg bl  phe_X  x y
 41   69   0  64   1 14 13 15.756  0 0
 52   70   0  41   1  4 13 11.141  3 0
 63   71   0  56   1 14 13 19.258  6 0
 74   72   0  55   1 14 13  4.775  9 0
 85   73   0  22   1  8 13 19.099 12 0
 96   74   0  50   1 14 13 19.258 15 0
10> dd$self = as.factor(dd$self)
11> ainv = asreml.Ainverse(ped)$ginv
12> mod1.as = asreml(phe_X ~ gg , random = ~ ped(self),ginverse = list(self = ainv), data=dd) 
13LogLikelihood Converged 
14> summary(mod1.as)$varcomp
15                  gamma component std.error  z.ratio constraint
16ped(self)!ped 0.2349996  3.396488  1.595445 2.128865   Positive
17R!variance    1.0000000 14.453164  1.529262 9.451070   Positive


结果是一样的。

于是我用另外一个数据集,进行测试,数据是使用的我编写的R包:learnasreml中的数据:


 1> library(learnasreml)
2> dat = animalmodel.dat
3> ped = animalmodel.ped
4> # asreml
5> ainv = asreml.Ainverse(ped)$ginv
6> mod2.as = asreml(BWT ~ SEX, random = ~ ped(ANIMAL), ginverse = list(ANIMAL = ainv), data=dat)
7LogLikelihood Converged 
8> summary(mod2.as)$varcomp
9                    gamma component std.error   z.ratio constraint
10ped(ANIMAL)!ped 0.2160062  2.494254 0.9180669  2.716855   Positive
11R!variance      1.0000000 11.547140 0.9386043 12.302458   Positive


方差组分Va为2.49,Ve为11.54。

使用breedR进行测试:


 1> dd2 = dat
2> mod2.br = remlf90(BWT ~ SEX, genetic =  list(model = "add_animal",pedigree = ped, id="ANIMAL"),data=dd2)
3> summary(mod2.br)
4Formula: BWT ~ 0 + SEX + pedigree 
5   Data: dd2 
6  AIC  BIC logLik
7 5941 5951  -2968
8Parameters of special components:
9Variance components:
10         Estimated variances   S.E.
11genetic               0.6651 0.6728
12Residual             13.3380 0.8602


纳尼?方差组分Va为0.66,Ve为13.33,这是什么鬼?和asreml不一样,据我对asreml的熟练程度,只有一种可能:那肯定是breedR有错误。于是我找到breedR的github中的issue:
上面问题描述:


Hi there,
I recently tried to fit an animal model using the remlf90() function. My model was simple and contained 4 fixed effects, 1 random non-genetic effect and the genetic additive effect (pedigree). I compared the results (h2 + se) to those of BLUPF90 (airemlf90) and they were the same as they should be. Then, I changed the class of the 'id' variable in the genetic part of the model from integer to factor and I re-ran the model. The h2 was considerabley different from that I got when the 'id' was of class integer.

So, is this normal, should the 'id' part of the genetic effect be always coded as integer or there is a bug that needs to be corrected?


作者回答,breedR需要个体的ID是数字型,如果是因子的话,会报错提醒啊。。。


Hi Nabeel.
Yes. The variables encoding individuals (i.e., id and progenitors) should be integers.
However, the pedigree-building function should have raisen an error whenever the user tries with a factor.
How did you specify the pedigree in the model?
Thanks for your report and help.


然后作者问了一句开发者经常问道的问题:你这个bug是如何得到的。。。

然而,有时候个体是factor时,真的没有报错,我也想提交一个issue,算了,还是自己解决吧!

我就把因子转化为了数字,运行breedR:


 1> dd2$ANIMAL = as.numeric(dd2$ANIMAL)
2> mod2.br = remlf90(BWT ~ SEX, genetic =  list(model = "add_animal",pedigree = ped, id="ANIMAL"),data=dd2)
3> summary(mod2.br)
4Formula: BWT ~ 0 + SEX + pedigree 
5   Data: dd2 
6  AIC  BIC logLik
7 5941 5951  -2968
8
9Parameters of special components:
10
11Variance components:
12         Estimated variances   S.E.
13genetic               0.6651 0.6728
14Residual             13.3380 0.8602


这个。。。也太真实了,结果不变,依旧是错误的。

于是,我陷入了深深的职业自我怀疑中:我是爱它的,为什么相爱的人不能在一起?

我左看右看,上看下看,还是没有找到问题的所在,我翻遍了breedR的issue,发现了这么一句话:


Regarding the issue of the variable type of the animal id, note that in the genetic component, the pedigree is taken from ped399, where the variable animal is presumably integer or numeric. However, if you change the corresponding variable in dat399 as you have been doing, this breaks the correspondence between the animal codes in the pedigree and the dataset.


大意就是说,breedR中,系谱和个体ID需要是数字,因为系谱的数据会在breedR中重新编码,如果你改变了数据中ID的编码,那么系谱构建的矩阵就和数据中的ID对应不了,结果就可能是错误的。

这一段正确的废话,并没有激起我什么想法,我还是继续沉浸于深深的自我怀疑中,一定是我不够好,所以它才想要逃。。。


灵感总是在梦中醒来,半夜忽然一个想法,是不是我转化数字的时候,变了?
但是数据中本来就是数字的因子类型啊,我把它转化为数字的数字类型时会变么?
我早知道R中有这种坑,在factor转化为number时,一定要通过character,否则会有各种不可预知的坑

难道
难道说
这个坑被我遇到了么???

第二天上班,我迫切的测试了一下:


1> tt = dat
2> head(tt$ANIMAL)
3[1] 1029 1299 643  1183 1238 891 
41084 Levels: 1 2 3 5 6 7 8 9 10 11 12 14 15 16 17 20 21 22 24 25 26 27 28 29 30 32 33 34 35 36 37 38 40 41 42 43 44 47 48 49 50 51 52 ... 1309
5> head(as.numeric(tt$ANIMAL))
6[1]  864 1076  549  989 1030  751


可以看到,变得面目全非,本来是1029,现在是864,本来是1299,现在是1076。

看完之后,我激动的心无法平静,竟然想起了“为何相爱的人不能在一起的旋律”,我也太难了,竟然是这个原因。。。

脑子里想起祥林嫂的语句:
我早知道,R中factor转化为number时有可能出错。。。

然后我用character作为中间元素,再测试了一下:


1> tt = dat
2> head(tt$ANIMAL)
3[1] 1029 1299 643  1183 1238 891 
41084 Levels: 1 2 3 5 6 7 8 9 10 11 12 14 15 16 17 20 21 22 24 25 26 27 28 29 30 32 33 34 35 36 37 38 40 41 42 43 44 47 48 49 50 51 52 ... 1309
5> head(as.numeric(as.character(tt$ANIMAL)))
6[1] 1029 1299  643 1183 1238  891


这就是对的了!

最后我用正确的形式,测试breedR中的动物模型:


 1> dd2 = dat
2> dd2$ANIMAL = as.numeric(as.character(dd2$ANIMAL))
3> mod2.br = remlf90(BWT ~ SEX, genetic =  list(model = "add_animal",pedigree = ped, id="ANIMAL"),data=dd2)
4> summary(mod2.br)
5Formula: BWT ~ 0 + SEX + pedigree 
6   Data: dd2 
7  AIC  BIC logLik
8 5931 5941  -2964
9
10Parameters of special components:
11
12
13Variance components:
14         Estimated variances   S.E.
15genetic                2.494 0.9181
16Residual              11.547 0.9386

终于看到了正确的结果,Va为2.49,Ve为11.54.

多么痛的领悟啊!

R中factor和number相互转化时,一定要经过character,这不是二手车市场,一定要有中间商赚差价!!!





http://blog.sciencenet.cn/blog-2577109-1203211.html

上一篇:进步青年自我麻痹三大件:健身,编程,学英语
下一篇:为什么体型比星座更能影响性格?

0

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...

Archiver|手机版|科学网 ( 京ICP备14006957 )

GMT+8, 2019-12-10 07:09

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部