我试图在R中运行一些相当深的递归代码并且它一直给我这个错误:
错误:C堆栈使用率太接近极限
我CStack_info()
的输出是:
Cstack_info()
size current direction eval_depth
67108864 8120 1 2
我的机器上有足够的内存,我只想弄清楚如何增加CS的CStack。
编辑:有人要求提供可重复的例子。这是导致问题的一些基本示例代码。运行f(1,1)几次就会出现错误。请注意,我已经设置了--max-ppsize = 500000和options(表达式= 500000),所以如果你没有设置它们,你可能会得到关于这两件事之一的错误。正如你所看到的,递归可以在这里非常深入,我不知道如何让它一致地工作。感谢。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)
}
答案 0 :(得分:47)
堆栈大小是一个操作系统参数,每个进程可调整(参见setrlimit(2)
)。据我所知,您无法在R内对其进行调整,但您可以在使用ulimit
命令启动R之前从shell调整它。它的工作原理如下:
$ ulimit -s # print default
8192
$ R --slave -e 'Cstack_info()["size"]'
size
8388608
8388608 = 1024 * 8192; R打印的值与ulimit -s
相同,但以字节为单位而不是千字节。
$ ulimit -s 16384 # enlarge stack limit to 16 megs
$ R --slave -e 'Cstack_info()["size"]'
size
16777216
要对此设置进行永久性调整,请将ulimit
命令添加到您的shell启动文件中,以便每次登录时执行该命令。我无法提供比那,因为它取决于你具有哪些外壳和东西。我也不知道如何登录图形环境(如果您没有在终端窗口中运行R,这将是相关的。)
答案 1 :(得分:16)
我怀疑,无论堆栈限制如何,你最终都会得到太深的递归。例如,使用lambda = Inf,f(1)会无限期地导致立即递归。递归的深度似乎是随机游走,有一些概率r更深,1-r完成当前递归。当你达到堆栈限制时,你已经做了很多“更深层次”的步骤。这意味着r> 1/2,而且绝大部分时间你都会继续递归。
此外,即使面对无限递归,似乎几乎可以推导出解析或至少数值解。可以将p定义为f(1)== 1的概率,在单次迭代后写入“子”状态的隐式表达式,并将它们与p等同,并求解。然后,p可以用作从二项分布中单次绘制成功的机会。
答案 2 :(得分:8)
这种情况发生在我身上是出于完全不同的原因。我在组合两列时不小心创建了一个超长字符串:
output_table_subset = mutate(big_data_frame,
combined_table = paste0(first_part, second_part, col = "_"))
而不是
output_table_subset = mutate(big_data_frame,
combined_table = paste0(first_part, second_part, sep = "_"))
让我永远想弄清楚,因为我从未预料到粘贴会导致问题。
答案 3 :(得分:3)
我遇到了接收&#34; C堆栈使用率太接近极限的问题&#34;错误(虽然对于另一个应用程序而不是上面user2045093所述的应用程序)。我尝试了zwol的建议,但它没有成功。
令我惊讶的是,我可以通过安装最新版本的R for OS X(目前版本为3.2.3)以及最新版本的R Studio for OS X(目前:0.99.840)来解决问题因为我正在使用R Studio。
希望这也可能对你有所帮助。
答案 4 :(得分:2)
此错误不是由于内存引起的,而是由于递归。函数正在调用自身。为了说明这一点,这是两个相互调用的函数的最小示例:
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")
错误:C堆栈使用量7971600太接近限制了
这些函数将继续递归地相互调用,并且理论上将永远不会完成。只有系统内的检查才能阻止这种情况的发生,并避免占用计算机的所有计算资源。您需要更改功能以确保它们不会递归调用自己(或彼此调用)。
答案 5 :(得分:1)
One issue here can be that you're calling f
inside itself
plop <- 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=) ?
答案 6 :(得分:0)
正如马丁摩根写的那样......问题是你在递归中得到了太深的内心。如果递归根本没有收敛,你需要自己打破它。我希望这段代码能够正常运行,因为它没有经过测试。但至少应该明确这一点。
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)
}
答案 7 :(得分:0)
引起相同问题的另一种方法:
library(debug)
mtrace(lapply)
在这里递归调用不太明显。
答案 8 :(得分:0)
如果您使用plot_ly,请检查要传递的列。似乎对于POSIXdt / ct列,您必须在传递给plotly之前使用as.character(),否则会收到此异常!
答案 9 :(得分:0)
对于所有人的信息,我突然在Windows 7(64位)上的R 3.6.1中遇到了这个问题。以前这不是问题,现在当我尝试“保存(。)”数据甚至执行“ save.image(。)”时,堆栈限制似乎随处可见。就像序列化将这些堆栈吹走了。
我正在认真考虑回落到3.6.0。在那里没有发生。
答案 10 :(得分:0)
我的情况也许是一个更独特的案例,但可能会帮助有这个确切问题的少数人:
我的情况绝对与空间使用无关,R仍然给出了:
C stack usage is too close to the limit
我有一个已定义的功能,它是基本功能的升级:
saveRDS()
但是,
偶然地,此定义的函数称为saveRDS()
而不是safe_saveRDS()
。
因此,超过该定义后,当代码到达wihch行时实际上使用saveRDS(...)
(它调用原始基本版本,而不是升级版本)时,它给出了以上错误并被破坏了。
因此,如果在调用某些保存功能时遇到该错误,请查看是否没有意外地对其进行处理。
答案 11 :(得分:0)
我经常在R脚本的顶部添加注释掉的source("path/to/file/thefile.R")
行,例如thefile.R
,因此我可以轻松地将其复制粘贴到终端中以运行它。如果忘记注释掉该行,则会出现此错误,因为运行文件会运行文件,文件会运行文件,文件会运行...
如果是原因,解决方案很简单:注释掉这一行。
答案 12 :(得分:0)
不确定我们是否要在此处列出问题,但是leaflet()
发生在我身上。
我正在尝试映射其中date
列属于类POSIXlt
的数据框。
改回POSIXct
解决了这个问题。
答案 13 :(得分:0)
在Linux上,我这样做是永久性地增加了堆栈和内存锁的大小:
* -- line 1 --
* -- line 2 --
° -- line 3 --
' -- line 4 --
° -- line 5 --
然后,在文件末尾添加以下行。
sudo vi /etc/security/limits.conf