2017-02-11 5 views
1

Ich versuche, ggplot innerhalb einer Funktion zu verwenden, aber ich kann die Plots nicht produzieren. Insbesondere möchte ich feststellen, ob der Plot facet_grid() aus dem Funktionsaufruf verwendet oder nicht. Dies ist meine Daten:Facettierung für ggplot innerhalb einer Funktion kann nicht verwendet werden

mydf <- data.frame(
    group = rep(c("g1", "g2"), each = 16, times = 1), 
    cluster = rep(c("c1", "c2"), each = 8, times = 2), 
    score1 = c(rnorm(n = 16, mean = 10, sd = 10), rnorm(n = 16, mean = 18, sd = 10)), 
    score2 = c(rnorm(n = 16, mean = 50, sd = 10), rnorm(n = 16, mean = 33, sd = 10)) 
) 

Hier ist die Funktion:

myFunc <- function(data, group = NULL, group2, var1, var2) { 

    # So we don't need quotation marks in function call 
    arguments <- as.list(match.call()) 
    var1 = eval(arguments$var1, data) 
    var2 = eval(arguments$var2, data) 
    group2 = eval(arguments$cluster, data) 
    grouping = eval(arguments$group, data) 

    # Make this graph if no faceting needed 
    if (length(grouping) == 0) { 

    means <- aggregate(cbind(var1, var2) ~ group2, FUN = mean, data = data) 

    ggplot(data, aes(x = var1, y = var2, color = group2, label = group2)) + 
    stat_ellipse(type = "norm", show.legend = FALSE, geom = "polygon", alpha = 0.1) + 
    geom_text(alpha = 0.5, show.legend = FALSE) + 
    geom_text(data = means, aes(x = var1, y = var2, color = group2)) 


    # Use faceting 
    } else if (length(grouping) > 0) { 

    means <- aggregate(cbind(var1, var2) ~ grouping + group2, FUN = mean, data = data) 

    # Plot 
    ggplot(data, aes(x = var1, y = var2, color = group2, label = group2)) + 
    stat_ellipse(type = "norm", show.legend = FALSE, geom = "polygon", alpha = 0.1) + 
    geom_text(alpha = 0.5, show.legend = FALSE) + 
    geom_text(data = means, aes(x = var1, y = var2, color = group2)) + 
    facet_grid(. ~ grouping) 

    } 

} 

ich die Funktion nenne etwa so:

myFunc(data = mydf, group = NULL, group2 = cluster, var1 = score1, var2 = score2) 
myFunc(data = mydf, group = group, group2 = cluster, var1 = score1, var2 = score2) 

Beiden Anrufe geben den folgenden Fehler jeweils:

# Error 1 
Error: Aesthetics must be either length 1 or the same as the data (32): x, y, colour, label 

# Error 2 
Error in combine_vars(data, params$plot_env, cols, drop = params$drop) : 
At least one layer must contain all variables used for facetting 

Der erwartete d-Ausgang kann durch den Bau der Grundstücke manuell erworben werden:

means <- aggregate(cbind(score1, score2) ~ group + cluster, FUN = mean, data = mydf) 

# without facet 
ggplot(mydf, aes(x = score1, y = score2, color = cluster, label = cluster)) + 
    stat_ellipse(type = "norm", show.legend = FALSE, geom = "polygon", alpha = 0.1) + 
    geom_text(alpha = 0.5, show.legend = FALSE) + 
    geom_text(data = means, aes(x = score1, y = score2, color = cluster)) 

# with facet 
ggplot(mydf, aes(x = score1, y = score2, color = cluster, label = cluster)) + 
    stat_ellipse(type = "norm", show.legend = FALSE, geom = "polygon", alpha = 0.1) + 
    geom_text(alpha = 0.5, show.legend = FALSE) + 
    geom_text(data = means, aes(x = score1, y = score2, color = cluster)) + 
    facet_grid(. ~ group) 

Antwort

2

Hier ist die Grund stat_ellipse Parzellen mit und ohne facet_grid zu verwenden. Ich werde dich die Schnörkel hinzufügen lassen. Hier werden die Spaltennamen als Strings gespeichert, so dass aes_string anstelle von aes verwendet wird und Formeln an Funktionen übergeben werden, die as.formula verwenden.

myFunc <- function(df, var1, var2, group2, group1 = NULL) { 

    # Make this graph if no faceting needed 
    if (is.null(group1)) { 

    means_formula <- as.formula(paste(var1, "+", var2, "~", group2)) 
    means <- aggregate(means_formula, FUN = mean, data = df) 

    p <- ggplot(df, 
     aes_string(x = var1, y = var2, color = group2, label = group2)) + 
     stat_ellipse(type = "norm", show.legend = FALSE, 
      geom = "polygon", alpha = 0.1) 
    }else{ 

    means_formula <- as.formula(paste(var1,"+",var2,"~", group2,"+",group1)) 
    means <- aggregate(means_formula, FUN = mean, data = df) 

    p <- ggplot(df, 
     aes_string(x = var1, y = var2, color = group2, label = group2)) + 
     stat_ellipse(type = "norm", show.legend = FALSE, 
      geom = "polygon", alpha = 0.1) + 
     facet_grid(as.formula(paste(".~ ",group1))) 
    } 
    print(p) 
} 

myFunc(df = mydf, var1 = "score1", var2 = "score2", 
    group2 = "cluster", group1 = NULL) 

myFunc(df = mydf, var1 = "score1", var2 = "score2", 
    group2 = "cluster", group1 = "group") 

stat ellipse plot

2

Zuerst werden Sie group2 auf eine nicht vorhandene Variable in Rahmen der Funktion zuweisen, cluster. Ersetzen: group2 = eval(arguments$cluster, data) mit group2 = eval(arguments$group2, data).

Zweitens benötigen Sie eine dynamische facet_grid Formel. Derzeit übergeben Sie Gruppierung, die kein tatsächliches Feld im Dataset ist. Da Sie jedoch in Funktionsargumenten ohne Anführungszeichen auskommen müssen, müssen Sie das Zeichenfolgenliteral des Funktionsarguments group abrufen, das mit deparse(substitute(...)) erreicht werden kann, um "group" zurückzugeben.

Betrachten Sie oben in der Nähe Liste der anderen Funktionsvariablen hinzu:

grpname = deparse(substitute(group)) 

Sie dann facet_grid ersetzen entweder mit einem dynamischen as.formula String-Verkettung oder mit reformulate:

facet_grid(as.formula(paste0(". ~ ", grpname))) 

facet_grid(reformulate(grpname)) 

Natürlich können alle sein dynamisch mit Funktionsarg in Anführungszeichen ausführen, wie von @ P-robot angezeigt.

Verwandte Themen