Estou tentando executar um código recursivo bastante profundo em R e ele continua me apresentando este erro:
Erro: o uso da pilha C está muito próximo do limite
Minha saída CStack_info()
é:
Cstack_info()
size current direction eval_depth
67108864 8120 1 2
Tenho muita memória em minha máquina, só estou tentando descobrir como posso aumentar o CStack para R.
EDIT: Alguém pediu um exemplo reproduzível. Aqui está um exemplo de código básico que causa o problema. Executando f (1,1) algumas vezes você obterá o erro. Observe que eu já configurei --max-ppsize = 500000 e options (expression = 500000), portanto, se você não configurá-los, poderá obter um erro sobre uma dessas duas coisas. Como você pode ver, a recursão pode ser muito profunda aqui e não tenho ideia de como fazê-la funcionar de forma consistente. Obrigado.
f <- function(root=1,lambda=1) {
x <- c(0,1);
prob <- c(1/(lambda+1),lambda/(lambda+1));
repeat {
if(root == 0) {
break;
}
else {
child <- sample(x,2,replace=TRUE,prob);
if(child[1] == 0 && child[2] == 0) {
break;
}
if(child[1] == 1) {
child[1] <- f(root=child[1],lambda);
}
if(child[2] == 1 && child[1] == 0) {
child[2] <- f(root=child[2],lambda);
}
}
if(child[1] == 0 && child[2] == 0) {
break;
}
if(child[1] == 1 || child[2] == 1) {
root <- sample(x,1,replace=TRUE,prob);
}
}
return(root)
}
options(expressions = somethinglarge)
Respostas:
O tamanho da pilha é um parâmetro do sistema operacional, ajustável por processo (consulte Recursos
setrlimit(2)
). Você não pode ajustá-lo de dentro de R, tanto quanto eu posso dizer, mas você pode ajustá-lo de shell antes de iniciar R, com oulimit
comando. Funciona assim:$ ulimit -s # print default 8192 $ R --slave -e 'Cstack_info()["size"]' size 8388608
8388608 = 1024 * 8192; R está imprimindo o mesmo valor
ulimit -s
, mas em bytes em vez de kilobytes.$ ulimit -s 16384 # enlarge stack limit to 16 megs $ R --slave -e 'Cstack_info()["size"]' size 16777216
Para fazer um ajuste permanente a esta configuração, adicione o
ulimit
comando ao seu arquivo de inicialização do shell, para que seja executado toda vez que você efetuar login. Não posso dar instruções mais específicas do que isso, porque depende exatamente de qual shell você tem e outras coisas. Eu também não sei como fazer isso para entrar em um ambiente gráfico (o que será relevante se você não estiver executando o R dentro de uma janela de terminal).fonte
unlimited
.RAppArmor
pacote oferece uma interface parasetrlimit(2)
. Essa funcionalidade pode ficar disponível noulimit
pacote em algum momento.Suspeito que, independentemente do limite de pilha, você acabará com recursões muito profundas. Por exemplo, com lambda = Inf, f (1) leva a uma recursão imediata, indefinidamente. A profundidade da recursão parece ser um passeio aleatório, com alguma probabilidade r de se aprofundar, 1 - r de terminar a recursão atual. No momento em que você atingiu o limite de pilha, você deu um grande número de etapas 'mais profundas'. Isso implica que r> 1/2 e, na grande maioria das vezes, você apenas continuará a recursão.
Além disso, parece que é quase possível derivar uma solução analítica ou pelo menos numérica, mesmo em face da recursão infinita. Pode-se definir p como a probabilidade de que f (1) == 1, escrever expressões implícitas para os estados 'filho' após uma única iteração e igualá-los a p e resolver. p pode então ser usado como a chance de sucesso em um único sorteio de uma distribuição binomial.
fonte
Este erro não é devido à memória , é devido à recursão . Uma função está chamando a si mesma. Para ilustrar o ponto, aqui está um exemplo mínimo de 2 funções que se chamam:
change_to_factor <- function(x){ x <- change_to_character(x) as.factor(x) } change_to_character <- function(x){ x <- change_to_factor(x) as.character(x) } change_to_character("1")
As funções continuarão a se chamar recursivamente e, teoricamente, nunca serão concluídas. São apenas verificações em seu sistema que evitam que isso ocorra indefinidamente e consuma todos os recursos de computação de sua máquina. Você precisa alterar as funções para garantir que elas não chamem a si mesmas (ou umas às outras) recursivamente.
fonte
Isso aconteceu comigo por um motivo completamente diferente. Eu acidentalmente criei uma string superlonga ao combinar duas colunas:
output_table_subset = mutate(big_data_frame, combined_table = paste0(first_part, second_part, col = "_"))
ao invés de
output_table_subset = mutate(big_data_frame, combined_table = paste0(first_part, second_part, sep = "_"))
Levei uma eternidade para descobrir, pois nunca esperei que a pasta tivesse causado o problema.
fonte
summarize( states = paste0(state,collapse=', ') )
. Quando eu deveria ter feito algo como:summarize( states = paste0(sort(unique(state)),collapse=', ') )
. O objetivo era obter uma lista separada por vírgulas de estados exclusivos disponíveis para cada subgrupo.Eu encontrei o mesmo problema de recebimento do erro "O uso da pilha C está muito próximo do limite" (embora para outro aplicativo que não o declarado pelo usuário 2045093 acima). Tentei a proposta de zwol, mas não deu certo.
Para minha própria surpresa, eu poderia resolver o problema instalando a versão mais recente do R para OS X (atualmente: versão 3.2.3), bem como a versão mais recente do R Studio para OS X (atualmente: 0.99.840), já que eu estou trabalhando com R Studio.
Esperançosamente, isso pode ser de alguma ajuda para você também.
fonte
Um problema aqui pode ser que você está chamando
f
dentro de siplop <- function(a = 2){ pouet <- sample(a) plop(pouet) } plop() Erreur : évaluations trop profondément imbriquées : récursion infinie / options(expressions=) ? Erreur pendant l'emballage (wrapup) : évaluations trop profondément imbriquées : récursion infinie / options(expressions=) ?
fonte
Para a informação de todos, de repente estou encontrando isso com R 3.6.1 no Windows 7 (64 bits). Não era um problema antes, e agora os limites de pilha parecem estar surgindo em todos os lugares, quando tento "salvar (.)" Dados ou até mesmo faço um "save.image (.)". É como se a serialização estivesse explodindo essas pilhas.
Estou pensando seriamente em voltar para a versão 3.6.0. Não aconteceu lá.
fonte
O meu é talvez um caso mais único, mas pode ajudar os poucos que têm este problema exato:
Meu caso não tem absolutamente nada a ver com uso de espaço, ainda R deu o:
C stack usage is too close to the limit
Eu tinha uma função definida que é uma atualização da função de base:
Mas,
acidentalmente, essa função definida foi chamada em
saveRDS()
vez desafe_saveRDS()
.Assim, além dessa definição, quando o código chegou à linha que realmente usa
saveRDS(...)
(que chama a versão base original, não a atualizada), ele deu o erro acima e esmagou.Portanto, se você está recebendo esse erro ao chamar alguma função de salvamento, veja se não a atropelou acidentalmente.
fonte
Como Martin Morgan escreveu ... O problema é que você se aprofunda demais na recursão. Se a recursão não convergir, você precisa quebrá-la sozinho. Espero que este código funcione, porque ele não foi testado. No entanto, pelo menos um ponto deve estar claro aqui.
f <- function(root=1,lambda=1,depth=1) { if(depth > 256){ return(NA) } x <- c(0,1); prob <- c(1/(lambda+1),lambda/(lambda+1)); repeat { if(root == 0) { break; } else { child <- sample(x,2,replace=TRUE,prob); if(child[1] == 0 && child[2] == 0) { break; } if(child[1] == 1) { child[1] <- f(root=child[1],lambda,depth+1); } if(child[2] == 1 && child[1] == 0) { child[2] <- f(root=child[2],lambda,depth+1); } } if(child[1] == NA | child[2] == NA){ return NA; } if(child[1] == 0 && child[2] == 0) { break; } if(child[1] == 1 || child[2] == 1) { root <- sample(x,1,replace=TRUE,prob); } } return(root) }
fonte
Outra forma de causar o mesmo problema:
library(debug) mtrace(lapply)
A chamada recursiva não é tão óbvia aqui.
fonte
Se você estiver usando plot_ly, verifique quais colunas você está passando. Parece que para colunas POSIXdt / ct, você tem que usar as.character () antes de passar para plotly ou você obterá esta exceção!
fonte
Costumo incluir uma
source("path/to/file/thefile.R")
linha comentada no topo de um script R, por exemplothefile.R
, para que possa copiar e colar facilmente no terminal para executá-lo. Recebo este erro se me esquecer de comentar a linha, uma vez que executar o arquivo executa o arquivo, que executa o arquivo, que executa o arquivo, ...Se for essa a causa, a solução é simples: comente a linha.
fonte