2016-03-04 2 views
5

Ich erhalte einen Fehler, wenn ich versuche, einen Parameter in die round Funktion innerhalb stat_summary zu übergeben (auch wenn der analoge Code funktioniert), sagen, geom_text). Hier ein Beispiel:ggplot2: stat_summary löst Fehler aus, wenn versucht wird, Funktionsargument als Parameter zu übergeben, anstatt hart zu codieren

# Fake data 
set.seed(5) 
dat = data.frame(group=rep(c("A","B"),each=10), val=rnorm(20)) 

Wir werden versuchen, die Anzahl der Dezimalstellen für die Wertelabels einen Parameter, anstatt hart codierte es:

places = 2 

ggplot(dat, aes(group, val)) + 
    stat_summary(fun.y=mean, geom="text", aes(label=round(..y.., places))) 

Fehler bei eval (ausdr , envir, enclos): Objekt 'Orte' nicht gefunden

Die folgenden zwei Beispiele funktionieren jedoch gut.

ggplot(dat, aes(group, val)) + 
    stat_summary(fun.y=mean, geom="text", aes(label=round(..y.., 2))) 

ggplot(dat, aes(group, val)) + 
    geom_text(aes(label=round(val, places))) 

Ich stieß auf dieses Problem beim Versuch, eine ggplot-Funktion zu schreiben. Zuerst dachte ich, das Problem ggplot nicht den Parameter aus der Funktionsumgebung zu erhalten, aber das Beispiel oben schlägt vor, dass das nicht das Problem ist. Der Vollständigkeit halber ist unten ein vereinfachtes Beispiel der Funktion zusammen mit der Fehlermeldung dargestellt. Die Funktion funktioniert gut, wenn ich das Ziffernargument fest auf round festcode, anstatt zu versuchen, den Parameter places zu übergeben.

pp1 = function(data, group, var, places=2, e=1.5) { 

    ggplot(data, aes_string(group, var)) + 
    geom_boxplot() + 
    stat_summary(fun.y=mean, geom="text", aes(label=round(..y.., places))) + 
    scale_y_continuous(limits = e * range(data[,var])) 

} 

pp1(dat, "group","val") 

Fehler bei eval (ausdr, envir, enclos): Objekt ‚Orte‘ nicht gefunden

Ich hoffe, um herauszufinden, ob ich etwas falsch und wie kann ich tun Erhalte das gewünschte Verhalten.

Ich bin R 3.2.3 und ggplot2 2.1.0 auf OS X 10.10.5 ausgeführt.

+1

Es sieht wie ein NSE-Problem aus. Sie können dem ausweichen, indem Sie 'eval (substitute (... ggplot code ..., list (places = places)))' aufrufen, obwohl es vielleicht einen besseren Weg gibt. – alistaire

+1

Das funktioniert. Bitte fügen Sie es als Antwort hinzu.Weißt du, warum es in 'stat_summary' passiert und nicht an anderen Orten? – eipi10

+0

Ich bin mir nicht sicher; Es geht darum, wie das NSE in 'aes' funktioniert. Vielleicht wird es von '..y..' eingeschaltet? Es gibt eine SE-Version mit dem Namen 'aes_', aber ich bin mir nicht sicher, wie ich das' ..y..' -Argument dazu bringen kann, darin zu arbeiten. Ich schreibe eine Antwort mit dem oben genannten und alles andere, was ich in Sekundenschnelle herausfinden kann. – alistaire

Antwort

2

aes verwendet non-standard evaluation, und wird daher versuchen, places innerhalb der data Argument bewerten Sie geben es. Das NSE variiert jedoch, je nachdem, was Sie übergeben.

Der typische Weg, um NSE zu umgehen, ist mit substitute, die, gut, ersetzt einen Wert innerhalb des Codes. Sie können dann eval verwenden den Code auszuführen:

eval(substitute(ggplot(dat, aes(group, val)) + 
        stat_summary(fun.y=mean, geom="text", aes(label=round(..y.., places))), 
       list(places = places))) 

, die wie erwartet funktioniert:

plot with labels

Hadley bietet auch mehrere SE-Versionen von aes: aes_, aes_q und aes_string, was wir können Sie vermeiden die Verwendung von substitute, aber die ich nicht ..y.. bewerten konnte. (Wenn jemand weiß, wie man es strukturiert, kommentieren und ich werde aktualisieren.)

Hadley erstellt auch die lazyeval package, die für die Verwaltung von NSE nützlich ist.