R: ошибка стека C при использовании рекурсивной функции - оптимизации кода - PullRequest
1 голос
/ 23 мая 2019

Я пытаюсь сделать простую «модель» потери первоначального значения на основе ряда критериев, как показано в моем коде ниже:

mtDNAlen = 16299
copies = 10
mito = 50
fraction = copies*mtDNAlen*0.75
Rounds = 40


A = data.frame(
  Length = c(rep(mtDNAlen,copies))
)
data = list()

for (i in 1:mito){
  data[[i]]=list()
}

for (i in 1:length(data)){
  for (j in 1:(Rounds+1)){
    data[[i]][[j]]=data.frame(A)
}}

finaldata = data.frame(X = seq(1,copies,1))

random.sample = function(x) {
  x = sample(sample.data, copies, 
             prob=Prob, 
             replace=FALSE)
  if (sum(x) > fraction) return(x)
  Recall(x)
}

for (i in 1:length(data)){
  for(j in 1:Rounds){
    data[[i]][[j]]$Deletion = sample(c("Yes","No"), nrow(data[[i]][[j]]), prob=c(0.05,0.95), replace=TRUE)
    data[[i]][[j]]$DelLength = ifelse(data[[i]][[j]]$Deletion == "Yes", sample(seq(0,15000,1), replace = TRUE),0)
    data[[i]][[j]]$Length = data[[i]][[j]]$Length - data[[i]][[j]]$DelLength
    data[[i]][[j]] = data[[i]][[j]][data[[i]][[j]]$Length > 2000,]
    data[[i]][[j]] = rbind(data[[i]][[j]],data[[i]][[j]])

    Prob = c(rep(16300,nrow(data[[i]][[j]]))) - data[[i]][[j]]$Length
    Prob = Prob / sum(Prob)

    sample.data = c(data[[i]][[j]]$Length)
    data[[i]][[j+1]]$Length = random.sample(sample.data)

    finaldata[[i]] = data[[i]][[j+1]]$Length
  }
}

Однако, когда я пытаюсь запустить свой код, я получаю следующую ошибку:

Error: C stack usage  7969700 is too close to the limit

После поиска это, кажется, происходит при использовании рекурсивных функций. Тем не менее, я новичок в этих типах функций, и я не знаю, как оптимизировать мой код дальше, чтобы исправить эту ошибку.

Я должен отметить, что когда я запускаю свой код без prob=Prob в функции random.sample, ошибки не возникает. Итак, я думаю, что ошибка возникает из-за необходимости повторять random.sample столько раз? Могу ли я сделать это лучше, чтобы избежать ошибки стека C? Я не смог найти альтернативу сам. Наконец, если я установлю Rounds и mito на очень маленькие значения, я смогу завершить вычисление, но это не очень удобно для меня ...

Спасибо!

EDIT

Я попытался вместо этого использовать repeat, чтобы мой for loop выглядел следующим образом:

for (i in 1:length(data)){
  for(j in 1:Rounds){
    data[[i]][[j]]$Deletion = sample(c("Yes","No"), nrow(data[[i]][[j]]), prob=c(0.05,0.95), replace=TRUE)
    data[[i]][[j]]$DelLength = ifelse(data[[i]][[j]]$Deletion == "Yes", sample(seq(0,15000,1), replace = TRUE),0)
    data[[i]][[j]]$Length = data[[i]][[j]]$Length - data[[i]][[j]]$DelLength
    data[[i]][[j]] = data[[i]][[j]][data[[i]][[j]]$Length > 2000,]
    data[[i]][[j]] = rbind(data[[i]][[j]],data[[i]][[j]])

    Prob = c(rep(16300,nrow(data[[i]][[j]]))) - data[[i]][[j]]$Length
    Prob = Prob / sum(Prob)

    sample.data = c(data[[i]][[j]]$Length)

    repeat {
      v2 <- sample(sample.data, copies, 
                   prob=Prob, 
                   replace=FALSE)
      if( sum(v2) > fraction ) 
        break
    } 
    return(v2)

    data[[i]][[j+1]]$Length = v2

    finaldata[[i]] = data[[i]][[j+1]]$Length
  }
}

Однако теперь я не могу получить данные выборки для перехода к следующему кадру данных, т.е. линия data[[i]][[j+1]]$Length = v2, кажется, не работает. Я вижу, что v2 генерируется и, похоже, хранит соответствующую форму и данные ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...