使用变量会占用我的数据点

时间:2013-11-25 22:22:06

标签: r statistics

进行统计分配(关于亲子鉴定)并认为我会使用R来帮助它。基本上我现在正在做的是尝试解析各种等位基因频率并计算假设的似然比 Alleged Father 实际上是无关系< / em>的

这是我的代码:

#Reading data
data.D1S80 = as.data.frame(read.table('Locus D1S80.txt'))
names(data.D1S80) = c("alleles", "counts")
#Getting empirical frequencies
pD1S80<-data.D1S80$counts/sum(data.D1S80$counts)
#Calculating the genotype probabilities under H(AF)
n<-length(pD1S80)
probHAF <-numeric (0)
for (i in 1:n){
  for (j in 1:n){
    for (k in 1:n){
      valueAF = 0
      if ((i==j)&(j==k)) {
        valueAF = pD1S80[i]^3
      } else if ((i==j)&(k!=i)) {
        valueAF = (pD1S80[i]^2)*pD1S80[k]
      } else if ((i!=j)&(k!=j)&(k!=i)) {
        valueAF = pD1S80[i]*pD1S80[j]*pD1S80[k] 
      } else if ((i=!j)&(j==k)&(i<j)) {
        valueAF = pD1S80[i]*pD1S80[j]*(pD1S80[i]+pD1S80[j])
      } else if ((i==k)&(i!=j)) {
        valueAF = pD1S80[j]*pD1S80[i]^2
      } 
      probHAF <-c(probHAF, valueAF)
    }
  }
}

所以基本上我试图通过组合表达式来找到经验等位基因频率。这个表达式总和为1。数据集有27个点和3个变量,因此我希望列出27^3 = 19683的顺序。我的代码给了我756,它似乎是27^2 + 27。我完全不知道它来自哪里。

问题在于这一点:

} else if ((i!=j)&(k!=j)&(k!=i)) {
  valueAF = pD1S80[i]*pD1S80[j]*pD1S80[k] 

如果我将值设置为常量,一切都很好(除了我得到不完整的分布)。有人可以帮帮我吗?我没办法。我也是R的新手,所以我很感激一个详细的答案!

非常感谢。

1 个答案:

答案 0 :(得分:4)

您可以使用expand.grid来避免for循环,以便一次生成所有索引。 然后用向量化的if替换所有elseifelse。这真的更快,无需在开始时分配内存。

例如,您可以像这样重写第一个嵌套条件:

pD1S80 <- round(rnorm(27),2)
id <- seq_along(pD1S80)
dat <- expand.grid(i=id,j=id,k=id)

valueAF <- with(dat,
     ifelse(i==j & j==k, pD1S80[i]^3,
            ifelse (i==j & k!=i,(pD1S80[i]^2)*pD1S80[k],
                                pD1S80[i]*pD1S80[j]*pD1S80[k] )))

基准

我的矢量化解决方案快了70倍。

microbenchmark(ag(),op(),times=1)
Unit: milliseconds
 expr        min         lq     median         uq        max neval
 ag()   31.52897   31.52897   31.52897   31.52897   31.52897     1
 op() 2181.76081 2181.76081 2181.76081 2181.76081 2181.76081     1

使用的功能是:

pD1S80 <- round(rnorm(27),2)
ag <- function(){
  id <- seq_along(pD1S80)
  dat <- expand.grid(i=id,j=id,k=id)
  valueAF <- with(dat,
     ifelse(i==j & j==k, pD1S80[i]^3,
            ifelse (i==j & k!=i,(pD1S80[i]^2)*pD1S80[k],
                                0 )))
  valueAF
}

op <- function(){
  probHAF <- numeric (0)
n <- length(pD1S80)
for (i in 1:n){
  for (j in 1:n){
    for (k in 1:n){
      valueAF = 0
      if ((i==j)&(j==k)) {
        valueAF = pD1S80[i]^3
      } else if ((i==j)&(k!=i)) {
        valueAF = (pD1S80[i]^2)*pD1S80[k]
      } 
      probHAF <-c(probHAF, valueAF)
    }}}
unlist(probHAF)
}