ggplot2 axis - Regressionsgeradengleichung und R2 im Diagramm hinzufügen




label position (5)

Ich frage mich, wie man die Regressionsgeradengleichung und R ^ 2 auf dem ggplot . Mein Code ist

library(ggplot2)
df <- data.frame(x = c(1:100))
df$y <- 2 + 3 * df$x + rnorm(100, sd = 40)
p <- ggplot(data = df, aes(x = x, y = y)) +
            geom_smooth(method = "lm", se=FALSE, color="black", formula = y ~ x) +
            geom_point()
p

Jede Hilfe wird sehr geschätzt.


Answers

Hier ist eine Lösung

# GET EQUATION AND R-SQUARED AS STRING
# SOURCE: http://goo.gl/K4yh

lm_eqn <- function(df){
    m <- lm(y ~ x, df);
    eq <- substitute(italic(y) == a + b %.% italic(x)*","~~italic(r)^2~"="~r2, 
         list(a = format(coef(m)[1], digits = 2), 
              b = format(coef(m)[2], digits = 2), 
             r2 = format(summary(m)$r.squared, digits = 3)))
    as.character(as.expression(eq));                 
}

p1 <- p + geom_text(x = 25, y = 300, label = lm_eqn(df), parse = TRUE)

BEARBEITEN. Ich habe herausgefunden, woher ich diesen Code genommen habe. Hier ist der link zum ursprünglichen Post in den Google Groups ggplot2


Ich habe Ramnaths Beitrag geändert, um a) generischer zu machen, so dass es ein lineares Modell als Parameter anstelle des Datenrahmens akzeptiert und b) Negative angemessener anzeigt.

lm_eqn = function(m) {

  l <- list(a = format(coef(m)[1], digits = 2),
      b = format(abs(coef(m)[2]), digits = 2),
      r2 = format(summary(m)$r.squared, digits = 3));

  if (coef(m)[2] >= 0)  {
    eq <- substitute(italic(y) == a + b %.% italic(x)*","~~italic(r)^2~"="~r2,l)
  } else {
    eq <- substitute(italic(y) == a - b %.% italic(x)*","~~italic(r)^2~"="~r2,l)    
  }

  as.character(as.expression(eq));                 
}

Die Verwendung würde sich ändern in:

p1 = p + geom_text(aes(x = 25, y = 300, label = lm_eqn(lm(y ~ x, df))), parse = TRUE)

Ich habe ein paar Zeilen der Quelle von stat_smooth und verwandten Funktionen geändert, um eine neue Funktion zu stat_smooth , die die Fit-Gleichung und den R-Quadrat-Wert hinzufügt. Dies wird auch auf Facettenplots funktionieren!

library(devtools)
source_gist("524eade46135f6348140")
df = data.frame(x = c(1:100))
df$y = 2 + 5 * df$x + rnorm(100, sd = 40)
df$class = rep(1:2,50)
ggplot(data = df, aes(x = x, y = y, label=y)) +
  stat_smooth_func(geom="text",method="lm",hjust=0,parse=TRUE) +
  geom_smooth(method="lm",se=FALSE) +
  geom_point() + facet_wrap(~class)

Ich habe den Code in @ Ramnaths Antwort verwendet, um die Gleichung zu formatieren. Die Funktion stat_smooth_func ist nicht sehr robust, aber es sollte nicht schwer sein damit stat_smooth_func .

https://gist.github.com/kdauria/524eade46135f6348140 . Versuchen Sie, ggplot2 aktualisieren, wenn Sie einen Fehler erhalten.


Ich habe eine Statistik stat_poly_eq() in mein Paket ggpmisc , die diese Antwort erlaubt:

library(ggplot2)
library(ggpmisc)
df <- data.frame(x = c(1:100))
df$y <- 2 + 3 * df$x + rnorm(100, sd = 40)
my.formula <- y ~ x
p <- ggplot(data = df, aes(x = x, y = y)) +
   geom_smooth(method = "lm", se=FALSE, color="black", formula = my.formula) +
   stat_poly_eq(formula = my.formula, 
                aes(label = paste(..eq.label.., ..rr.label.., sep = "~~~")), 
                parse = TRUE) +         
   geom_point()
p

Diese Statistik funktioniert mit jedem Polynom ohne fehlende Terme und hat hoffentlich genug Flexibilität, um allgemein nützlich zu sein. Die Label R ^ 2 oder adjusted R ^ 2 können mit jeder Modellformel verwendet werden, die mit lm () ausgestattet ist. Da es sich um eine ggplot-Statistik handelt, verhält es sich wie erwartet sowohl mit Gruppen als auch mit Facetten.

Das Paket 'ggpmisc' ist über CRAN verfügbar.

Version 0.2.6 wurde gerade in CRAN akzeptiert.

Es adressiert Kommentare von @shabbychef und @ MYaseen208.

@ MYaseen208 zeigt, wie ein Hut hinzugefügt wird.

library(ggplot2)
library(ggpmisc)
df <- data.frame(x = c(1:100))
df$y <- 2 + 3 * df$x + rnorm(100, sd = 40)
my.formula <- y ~ x
p <- ggplot(data = df, aes(x = x, y = y)) +
   geom_smooth(method = "lm", se=FALSE, color="black", formula = my.formula) +
   stat_poly_eq(formula = my.formula,
                eq.with.lhs = "italic(hat(y))~`=`~",
                aes(label = paste(..eq.label.., ..rr.label.., sep = "~~~")), 
                parse = TRUE) +         
   geom_point()
p

@shabbychef Jetzt ist es möglich, die Variablen in der Gleichung mit denen für die Achsenbeschriftungen zu vergleichen. Um das x durch sagen z und y mit h zu ersetzen, würde man verwenden:

p <- ggplot(data = df, aes(x = x, y = y)) +
   geom_smooth(method = "lm", se=FALSE, color="black", formula = my.formula) +
   stat_poly_eq(formula = my.formula,
                eq.with.lhs = "italic(h)~`=`~",
                eq.x.rhs = "~italic(z)",
                aes(label = ..eq.label..), 
                parse = TRUE) + 
   labs(x = expression(italic(z)), y = expression(italic(h))) +          
   geom_point()
p

Da diese normalen R-geparsten Ausdrücke griechische Buchstaben sind, können sie nun auch in den lhs und rhs der Gleichung verwendet werden.

[2017-03-08] @elarry Edit, um die ursprüngliche Frage präziser zu adressieren und zu zeigen, wie man ein Komma zwischen die Formel- und R2-Label fügt.

p <- ggplot(data = df, aes(x = x, y = y)) +
  geom_smooth(method = "lm", se=FALSE, color="black", formula = my.formula) +
  stat_poly_eq(formula = my.formula,
               eq.with.lhs = "italic(hat(y))~`=`~",
               aes(label = paste(..eq.label.., ..rr.label.., sep = "*plain(\",\")~")), 
               parse = TRUE) +         
  geom_point()
p


Sie sollten .SDcols (vor allem, wenn Sie zu viele Spalten haben und eine bestimmte Operation nur für eine Teilmenge der Spalten erforderlich ist (abgesehen von den Gruppierungsvariablenspalten).

dtb[, lapply(.SD, mean), by=condition, .SDcols=2:4]

#    condition  var1   var2    var3
# 1:       one 101.0 1001.0 10001.0
# 2:       two 104.0 1004.0 10004.0
# 3:     three 107.0 1007.0 10007.0
# 4:      four 109.5 1009.5 10009.5

Sie könnten auch alle Spaltennamen erhalten, die Sie als erstes in einer Variablen annehmen möchten, und diese dann an .SDcols :

keys <- setdiff(names(dtb), "condition")
# keys = var1, var2, var3
dtb[, lapply(.SD, mean), by=condition, .SDcols=keys]

Edit: Wie Matthew Dowle zu Recht angemerkt hat, können Sie einfach Folgendes tun, wenn Sie möchten, dass nach der Gruppierung nach condition Mittelwert für jede andere Spalte berechnet wird:

dtb[, lapply(.SD, mean), by=condition]

Davids Bearbeitung: (die abgelehnt wurde): Lesen Sie mehr über .SD von diesem Beitrag . Ich finde das hier relevant. Danke @David.

Edit 2: Angenommen, Sie haben eine data.table mit 1000 Zeilen und 301 Spalten (eine Spalte zum Gruppieren und 300 numerische Spalten):

require(data.table)
set.seed(45)
dt <- data.table(grp = sample(letters[1:15], 1000, replace=T))
m  <- matrix(rnorm(300*1000), ncol=300)
dt <- cbind(dt, m)
setkey(dt, "grp")

und du wolltest den Mittelwert der Spalten finden, sagen wir, 251: 300 allein,

  • Sie können den Mittelwert aller Spalten berechnen und dann diese Spalten unterteilen (was nicht sehr effizient ist, da Sie die gesamten Daten berechnen).

    dt.out <- dt[, lapply(.SD, mean), by=grp]
    dim(dt.out) # 15 * 301, not efficient.
    
  • Sie können die data.table zuerst nur auf diese Spalten filtern und dann den Mittelwert berechnen (was wiederum nicht unbedingt die beste Lösung ist, da Sie jedes Mal, wenn Sie Operationen für bestimmte Spalten ausführen wollen, eine zusätzliche Datentabelle erstellen müssen.

    dt.sub <- dt[, c(1, 251:300), with=FALSE]
    setkey(dt.sub, "grp")
    dt.out <- dt.sub[, lapply(.SD, mean), by=grp]
    
  • Sie können jede der Spalten wie gewohnt einzeln angeben (dies ist jedoch für kleinere data.tables wünschenswert)

    # if you just need one or few columns
    dt.out <- dt[, list(m.v251 = mean(V251)), by = grp]
    

Was ist die beste Lösung? Die Antwort lautet .SDcols .

Wie in der Dokumentation angegeben, gibt .SDcols für eine data.table x die Spalten an, die in .SD enthalten sind .

Im Grunde filtert dies implizit die Spalten, die an .SD übergeben werden, anstatt eine Teilmenge zu erstellen (wie wir es vorher getan haben), nur ist es SEHR effizient und SCHNELL!

Wie können wir das tun?

  • Indem Sie entweder die Spaltennummern angeben:

    dt.out <- dt[, lapply(.SD, mean), by=grp, .SDcols = 251:300]
    dim(dt.out) # 15 * 51 (what we expect)
    
  • Oder alternativ durch Angabe der Spalten-ID:

    ids <- paste0("V", 251:300) # get column ids
    dt.out <- dt[, lapply(.SD, mean), by=grp, .SDcols = ids]
    dim(dt.out) # 15 * 51 (what we expect)
    

Es akzeptiert sowohl Spaltennamen als auch Zahlen als Argumente. In beiden Fällen wird .SD nur mit den von uns angegebenen Spalten bereitgestellt.

Hoffe das hilft.





r ggplot2 ggpmisc