2015-10-21 10 views
7

Non ho esperienza con i loop ma sembra che avrò bisogno di crearne alcuni per analizzare correttamente i miei dati. Potresti mostrare come creare un semplice ciclo sul codice che ho già creato? Usiamo il ciclo per ottenere alcuni grafici:Scrittura di un ciclo per creare figure ggplot con origini dati e titoli diversi

pdf(file = sprintf("complex I analysis", tbl_comp_abu1), paper='A4r') 

ggplot(df_tbl_data1_comp1, aes(Size_Range, Abundance, group=factor(Gene_Name))) + 
    theme(legend.title=element_blank()) + 
    geom_line(aes(color=factor(Gene_Name))) + 
    ggtitle("Data1 - complex I")+ 
    theme(axis.text.x = element_text(angle = 90, hjust = 1)) 

ggplot(df_tbl_data2_comp1, aes(Size_Range, Abundance, group=factor(Gene_Name))) + 
    theme(legend.title=element_blank()) + 
    geom_line(aes(color=factor(Gene_Name))) + 
    ggtitle("Data2 - complex I")+ 
    theme(axis.text.x = element_text(angle = 90, hjust = 1)) 


ggplot(df_tbl_data3_comp1, aes(Size_Range, Abundance, group=factor(Gene_Name))) + 
    theme(legend.title=element_blank()) + 
    geom_line(aes(color=factor(Gene_Name))) + 
    ggtitle("Datas3 - complex I")+ 
    theme(axis.text.x = element_text(angle = 90, hjust = 1)) 

dev.off() 

La domanda ora è ciò che vorrei ottenere. Quindi prima di tutto ho bisogno di 10 complessi da analizzare, quindi significa che devono essere creati 10 file PDF e l'esempio mostra grafici di tre diversi set di dati per il complesso. Per farlo correttamente, il numero nella variabile comp1 (da df_tbl_dataX_comp1) deve essere modificato da 1 a 10 - dipende dal complesso che vogliamo tracciare. La prossima cosa che deve essere cambiata attraverso il ciclo è il nome del file pdf e ciascuno dei grafici ... È possibile scrivere tale ciclo?

dati:

structure(list(Size_Range = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 
3L, 3L, 3L, 4L, 4L, 4L, 5L, 5L, 5L, 6L, 6L, 6L, 7L, 7L, 7L, 8L, 
8L, 8L, 9L, 9L, 9L, 10L, 10L, 10L, 11L, 11L, 11L, 12L, 12L, 12L, 
13L, 13L, 13L, 14L, 14L, 14L, 15L, 15L, 15L, 16L, 16L, 16L, 17L, 
17L, 17L, 18L, 18L, 18L, 19L, 19L, 19L, 20L, 20L, 20L), .Label = c("10", 
"34", "59", "84", "110", "134", "165", "199", "234", "257", "362", 
"433", "506", "581", "652", "733", "818", "896", "972", "1039" 
), class = "factor"), Abundance = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 142733.475, 108263.525, 98261.11, 649286.165, 
3320759.803, 3708515.148, 6691260.945, 30946562.92, 180974.3725, 
4530005.805, 21499827.89, 0, 15032198.54, 4058060.583, 0, 3842964.97, 
2544030.857, 0, 1640476.977, 286249.1775, 0, 217388.5675, 1252965.433, 
0, 1314666.05, 167467.8825, 0, 253798.15, 107244.9925, 0, 207341.1925, 
15755.485, 0, 71015.85, 14828.5075, 0, 25966.2325, 0, 0, 0, 0, 
0, 0), Gene_Name = c("AT1G01080", "AT1G01090", "AT1G01320", "AT1G01420", 
"AT1G01470", "AT1G01560", "AT1G01800", "AT1G02150", "AT1G02500", 
"AT1G02560", "AT1G02780", "AT1G02880", "AT1G02920", "AT1G02930", 
"AT1G03030", "AT1G03090", "AT1G03110", "AT1G03130", "AT1G03220", 
"AT1G03230", "AT1G03330", "AT1G03475", "AT1G03630", "AT1G03680", 
"AT1G03870", "ATCG00420", "ATCG00470", "ATCG00480", "ATCG00490", 
"ATCG00500", "ATCG00650", "ATCG00660", "ATCG00670", "ATCG00740", 
"ATCG00750", "ATCG00842", "ATCG01100", "ATCG01030", "ATCG01114", 
"ATCG01665", "ATCG00770", "ATCG00780", "ATCG00800", "ATCG00810", 
"ATCG00820", "ATCG00722", "ATCG00744", "ATCG00855", "ATCG00853", 
"ATCG00888", "ATCG00733", "ATCG00766", "ATCG00812", "ATCG00821", 
"ATCG00856", "ATCG00830", "ATCG00900", "ATCG01060", "ATCG01110", 
"ATCG01120")), .Names = c("Size_Range", "Abundance", "Gene_Name" 
), row.names = c(NA, -60L), class = "data.frame") 
+2

Si potrebbe verificare: http://stackoverflow.com/questions/23439266/list-for-multiple-plots-from-loop-ggplot2-list-elements - sovrascrivibile o http://stackoverflow.com/questions/11357139/r-saving-ggplot2-plots-in-a-list?rq=1 – Iris

+0

I tuoi dati sono molto grandi?Potresti prendere in considerazione la creazione di un elenco con nome di dataframes (o anche di uno grande) e usando 'lapply' o qualcosa di simile. – Heroka

+0

Non sono così grandi. Potrebbe facilmente farlo se io sapessi come ... –

risposta

3

Questo potrebbe fare il trucco: Iniziato due anelli, uno per il complesso iterazione e una seconda per l'iterazione set di dati. Quindi utilizzare paste0() o paste() per generare i nomi file e le intestazioni corretti.

PS: non ho testato il codice, poiché non ho i tuoi dati. Ma dovrebbe darti un'idea.

#loop over complex  
for (c in 1:10) { 

    #create pdf for every complex 
    pdf(file = paste0("complex", c, "analysis.pdf"), paper='A4r') 

    #loop over datasets 
    for(d in 1:3) { 

    #plot 
    ggplot(get(paste0("df_tbl_data",d,"_comp",c)), aes(Size_Range, Abundance, group=factor(Gene_Name))) + 
     theme(legend.title=element_blank()) + 
     geom_line(aes(color=factor(Gene_Name))) + 
     ggtitle(paste0("Data",d," - complex ",c))+ 
     theme(axis.text.x = element_text(angle = 90, hjust = 1)) 
    } 
    dev.off() 

} 
+0

Crea file ma senza alcuna estensione (intendo senza estensione "pdf"). Anche se lo cambio manualmente in pdf non apre il file. –

+0

@ShaxiLiver cosa è 'tbl_comp_abu1'? – maRtin

+0

È solo un frame di dati che è stato utilizzato per tracciare qualcos'altro. È importante ? Funziona per me quando applico il codice dal primo post. –

2

Quindi, dopo aver fatto la mia risposta, mi sono reso conto che non affronta la vera domanda sui loop. Tuttavia, spero che ti mostri un modo diverso di affrontare il tuo problema di root (a.k.a non volevo che il lavoro andasse sprecato).

Non riuscivo a far funzionare la trama con i dati che hai postato. Esistono 60 nomi di geni univoci in un frame di dati di 60 righe. Quando si tenta di creare un gruppo geom_line e un gruppo in base a un valore (aes(group=Gene_name)), è necessario un solo punto per ogni riga. Hai bisogno di due punti per fare una linea.

Ho inventato alcuni dati e fatto un'analisi.

# Function to generate random data 
generate_data = function() { 
    require(truncnorm) 
    require(dplyr) 

    gene_names = LETTERS[1:20] 
    n_genes = length(gene_names) 
    size_ranges = c(10, 34, 59, 84, 110, 134, 165, 199, 
        234, 257, 362, 433, 506, 581, 652, 
        733, 818, 896, 972, 1039) 
    gene_size_means = rtruncnorm(n_genes, 10, 1000, 550, 300) 
    genes_in_complex = rbinom(n_genes, 1, 0.3) 
    true_variance = 50 
    gene_size_variances = rchisq(n_genes, n_genes-1) * (true_variance/(n_genes-1)) 
    df = data.frame(gene_name=gene_names, 
        gene_mean=gene_size_means, 
        gene_var=gene_size_variances, 
        in_complex=genes_in_complex) 
    df = df %>% group_by(gene_name) %>% 
    do(data.frame(size_ranges, 
        abundance=dnorm(size_ranges, .$gene_mean, .$gene_var)*.$in_complex)) 
    return(df) 
} 

# Generate a list of tables. Each table is for one data set for one complex 
data_tables = list() 
n_comps = 3 
for(complex_i in 1:2) { 
    for(comp_j in 1:n_comps) { 
    loop_df = generate_data() 
    loop_df$comp = comp_j 
    loop_df$complex = complex_i 
    data_tables = c(data_tables, list(loop_df)) 
    } 
} 

# Concatenate the tables into a larger data frame 
dat = do.call(rbind, data_tables) 

# Make a plots for each data set for complex 1 
dat_complex1 = subset(dat, complex==1) 
p = ggplot(dat_complex1, aes(x=size_ranges, y=abundance, color=gene_name, group=gene_name)) + 
    geom_line() + 
    facet_wrap(~comp, ncol=1) 
print(p) 

# Make a plot with many subpanels for all complexes and data sets 
p %+% dat + facet_grid(comp~complex) # screenshot shown below 

enter image description here

Così si sta studiando complessi proteici in Arabidopsis? Nel caso qualcuno abbia familiarità con il tuo dominio, una frase di sottofondo potrebbe aiutarli a rispondere alla tua domanda. In alternativa, una foto dell'output desiderato potrebbe aiutare. Inoltre, alcuni dati e/o screenshot di esempio più completi potrebbero generare più interesse per i tuoi post futuri.

1

Dai un'occhiata a questo approccio. Dipende da un data.frame (dat) che contiene i nomi dei set di dati, i titoli dei grafici e i nomi dei file.

prima cosa creare una funzione che crea la trama e lo salva, poi chiamo la funzione in un for -loop e anche in un apply -loop (uso applicare, ove possibile, il suo più veloce).

Il codice simile a questo:

# create a custom function for ggplot, 
# which creates the plot and then saves it as a pdf 
custom_ggplot_function <- function(input.data.name, graph.title, f.name){ 
    # get(input.data.name) gets you the variable which is stored as a string in 
    # input.data.name 

    p <- ggplot(get(input.data.name), aes(Size_Range, Abundance, group=factor(Gene_Name))) + 
    theme(legend.title=element_blank()) + 
    geom_line(aes(color=factor(Gene_Name))) + 
    ggtitle(graph.title)+ 
    theme(axis.text.x = element_text(angle = 90, hjust = 1)) 

    ggsave(filename = paste0(f.name, ".pdf"), plot = p) 
    NULL 
} 

# dat contains the names of your datasets, the titles of the graphs and filenames 
dat <- data.frame(df.names = c("df_tbl_data1_comp1", 
           "df_tbl_data2_comp1"), 
        graph.titles = c("Data1 - Complex I", 
            "Data2 - Complex II"), 
        file.names = c("file1", "file2")) 
# If you create your data.frame dat, you can also say 
# df.names = paste0("df_tbl_data", 1:10, "_comp1") and 
# graph.titles = paste0("Data", 1:10, " - Complex ", 1:10)  


# loop through the rows of dat 
for (i in 1:nrow(dat)) { 
    custom_ggplot_function(input.data.name = dat[i, "df.names"], 
         graph.title = dat[i, "graph.titles"], 
         f.name = dat[i, "file.names"]) 
} 

# or using the apply function 
apply(dat, 1, function(row.el) { 
    custom_ggplot_function(input.data.name = row.el["df.names"], 
         graph.title = row.el["graph.titles"], 
         f.name = row.el["file.names"]) 
}) 
Problemi correlati