Ich versuche, einen ziemlich tiefen rekursiven Code in R auszuführen, und es gibt mir immer wieder den folgenden Fehler:
Fehler: Die Verwendung des C-Stacks liegt zu nahe am Grenzwert
Meine Ausgabe von CStack_info()
ist:
Cstack_info()
size current direction eval_depth
67108864 8120 1 2
Ich habe viel Speicher auf meinem Computer. Ich versuche nur herauszufinden, wie ich den CStack für R erhöhen kann.
EDIT: Jemand hat nach einem reproduzierbaren Beispiel gefragt. Hier ist ein grundlegender Beispielcode, der das Problem verursacht. Wenn Sie f (1,1) einige Male ausführen, wird der Fehler angezeigt. Beachten Sie, dass ich bereits --max-ppsize = 500000 und Optionen (Ausdrücke = 500000) festgelegt habe. Wenn Sie diese nicht festlegen, wird möglicherweise stattdessen eine Fehlermeldung zu einem dieser beiden Dinge angezeigt. Wie Sie sehen können, kann die Rekursion hier ziemlich tief gehen, und ich habe keine Ahnung, wie ich sie konsistent zum Laufen bringen kann. Vielen Dank.
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)
Antworten:
Die Stapelgröße ist ein pro Prozess einstellbarer Betriebssystemparameter (siehe
setrlimit(2)
). Sie können es nicht innerhalb von R anpassen, soweit ich das beurteilen kann, aber Sie können es über die Shell anpassen, bevor Sie R mit demulimit
Befehl starten . Es funktioniert so:$ ulimit -s # print default 8192 $ R --slave -e 'Cstack_info()["size"]' size 8388608
8388608 = 1024 * 8192; R druckt den gleichen Wert wie
ulimit -s
, jedoch in Bytes anstelle von Kilobytes.$ ulimit -s 16384 # enlarge stack limit to 16 megs $ R --slave -e 'Cstack_info()["size"]' size 16777216
Um diese Einstellung dauerhaft anzupassen, fügen Sie den
ulimit
Befehl zu Ihrer Shell-Startdatei hinzu, damit er jedes Mal ausgeführt wird, wenn Sie sich anmelden. Ich kann keine genaueren Anweisungen geben, da dies genau davon abhängt, welche Shell Sie haben und was. Ich weiß auch nicht, wie ich mich in einer grafischen Umgebung anmelden soll (was relevant ist, wenn Sie R nicht in einem Terminalfenster ausführen).quelle
unlimited
.RAppArmor
Paket bietet eine Schnittstelle zusetrlimit(2)
. Diese Funktionalität wird möglicherweiseulimit
irgendwann im Paket verfügbar sein.Ich vermute, dass Sie unabhängig von der Stapelbeschränkung zu tiefe Rekursionen erhalten. Zum Beispiel führt f (1) mit Lambda = Inf zu einer sofortigen Rekursion auf unbestimmte Zeit. Die Tiefe der Rekursion scheint ein zufälliger Spaziergang zu sein, mit einer gewissen Wahrscheinlichkeit r, tiefer zu gehen, 1 - r, die aktuelle Rekursion zu beenden. Bis Sie das Stapellimit erreicht haben, haben Sie eine große Anzahl von Schritten "tiefer" gemacht. Dies impliziert, dass r> 1/2 ist und Sie die meiste Zeit nur weiter rekursieren.
Es scheint auch fast möglich zu sein, eine analytische oder zumindest numerische Lösung abzuleiten, selbst angesichts einer unendlichen Rekursion. Man kann p als die Wahrscheinlichkeit definieren, dass f (1) == 1 ist, implizite Ausdrücke für die 'Kind'-Zustände nach einer einzelnen Iteration schreiben und diese mit p gleichsetzen und lösen. p kann dann als Erfolgschance bei einem einzelnen Draw aus einer Binomialverteilung verwendet werden.
quelle
Dieser Fehler ist nicht auf den Speicher zurückzuführen, sondern auf die Rekursion . Eine Funktion ruft sich selbst auf. Um den Punkt zu veranschaulichen, hier ein minimales Beispiel für zwei Funktionen, die sich gegenseitig aufrufen:
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")
Die Funktionen rufen sich weiterhin rekursiv auf und werden theoretisch nie abgeschlossen. Es sind nur Überprüfungen in Ihrem System, die verhindern, dass dies auf unbestimmte Zeit auftritt und alle Rechenressourcen Ihres Computers verbraucht. Sie müssen die Funktionen ändern, um sicherzustellen, dass sie sich selbst (oder einander) nicht rekursiv aufrufen.
quelle
Das ist mir aus einem ganz anderen Grund passiert. Ich habe versehentlich eine superlange Zeichenfolge erstellt, während ich zwei Spalten kombiniert habe:
output_table_subset = mutate(big_data_frame, combined_table = paste0(first_part, second_part, col = "_"))
anstatt
output_table_subset = mutate(big_data_frame, combined_table = paste0(first_part, second_part, sep = "_"))
Ich habe ewig gebraucht, um es herauszufinden, da ich nie erwartet hätte, dass die Paste das Problem verursacht hat.
quelle
summarize( states = paste0(state,collapse=', ') )
. Wenn ich etwas hätte tun sollen wie :summarize( states = paste0(sort(unique(state)),collapse=', ') )
. Ziel war es, eine durch Kommas getrennte Liste eindeutiger Zustände für jede Untergruppe zu erhalten.Ich habe das gleiche Problem beim Empfang des Fehlers "C-Stack-Nutzung ist zu nahe am Limit" festgestellt (allerdings für eine andere Anwendung als die oben von user2045093 angegebene). Ich habe den Vorschlag von zwol ausprobiert, aber es hat nicht geklappt.
Zu meiner eigenen Überraschung konnte ich das Problem lösen, indem ich die neueste Version von R für OS X (derzeit: Version 3.2.3) sowie die neueste Version von R Studio für OS X (derzeit: 0.99.840) installierte, seit ich arbeite mit R Studio.
Hoffentlich kann Ihnen dies auch weiterhelfen.
quelle
Ein Problem hier kann sein, dass Sie in sich
f
selbst anrufenplop <- 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=) ?
quelle
Zur Information aller stoße ich plötzlich mit R 3.6.1 unter Windows 7 (64-Bit) darauf. Früher war das kein Problem, und jetzt scheinen überall Stapelbeschränkungen aufzutauchen, wenn ich versuche, Daten zu "speichern (.)" Oder sogar ein "save.image (.)" Zu erstellen. Es ist, als würde die Serialisierung diese Stapel wegblasen.
Ich denke ernsthaft darüber nach, auf 3.6.0 zurückzugreifen. Ist dort nicht passiert.
quelle
Meins ist vielleicht ein einzigartiger Fall, kann aber den wenigen helfen, die genau dieses Problem haben:
Mein Fall hat absolut nichts mit Platznutzung zu tun, dennoch gab R Folgendes:
C stack usage is too close to the limit
Ich hatte eine definierte Funktion, die ein Upgrade der Basisfunktion darstellt:
Aus
Versehen wurde diese definierte Funktion jedoch
saveRDS()
anstelle von aufgerufensafe_saveRDS()
.Nach dieser Definition gab der Code, wenn er in die Zeile gelangt, die tatsächlich verwendet wird
saveRDS(...)
(die die ursprüngliche Basisversion aufruft, nicht die aktualisierte), den obigen Fehler aus und wurde zerstört.Wenn Sie diesen Fehler beim Aufrufen einer Speicherfunktion erhalten, prüfen Sie, ob Sie ihn nicht versehentlich überfahren haben.
quelle
Wie Martin Morgan schrieb ... Das Problem ist, dass Sie zu tief in die Rekursion geraten. Wenn die Rekursion überhaupt nicht konvergiert, müssen Sie sie selbst brechen. Ich hoffe, dieser Code wird funktionieren, da er nicht getestet wird. Zumindest Punkt sollte hier jedoch klar sein.
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) }
quelle
Ein anderer Weg, um das gleiche Problem zu verursachen:
library(debug) mtrace(lapply)
Der rekursive Aufruf ist hier nicht so offensichtlich.
quelle
Wenn Sie plot_ly verwenden, überprüfen Sie, welche Spalten Sie übergeben. Es scheint, dass Sie für POSIXdt / ct-Spalten as.character () verwenden müssen, bevor Sie an plotly übergeben, sonst erhalten Sie diese Ausnahme!
quelle
Ich füge häufig eine auskommentierte
source("path/to/file/thefile.R")
Zeile oben in ein R-Skript ein, z. B.thefile.R
damit ich diese einfach kopieren und in das Terminal einfügen kann, um es auszuführen. Ich erhalte diese Fehlermeldung, wenn ich vergesse, die Zeile zu kommentieren, da beim Ausführen der Datei die Datei ausgeführt wird, bei der die Datei ausgeführt wird, bei der die Datei ausgeführt wird, ...Wenn dies die Ursache ist, ist die Lösung einfach: Kommentieren Sie die Zeile aus.
quelle