Domanda

Ho un frame di dati con più colonne, uno dei quali è un fattore chiamato "portale". Come posso dividere il frame di dati in blocchi di righe ognuna con un valore unico di "site", e quindi elaborare ogni blocco con una funzione? I dati appaiono così:

site year peak
ALBEN 5 101529.6
ALBEN 10 117483.4
ALBEN 20 132960.9
ALBEN 50 153251.2
ALBEN 100 168647.8
ALBEN 200 184153.6
ALBEN 500 204866.5
ALDER 5 6561.3
ALDER 10 7897.1
ALDER 20 9208.1
ALDER 50 10949.3
ALDER 100 12287.6
ALDER 200 13650.2
ALDER 500 15493.6
AMERI 5 43656.5
AMERI 10 51475.3
AMERI 20 58854.4
AMERI 50 68233.3
AMERI 100 75135.9
AMERI 200 81908.3

e voglio creare un terreno di year vs peak per ogni sito.

È stato utile?

Soluzione

Un'altra scelta è utilizzare la funzione ddply dalla libreria ggplot2. Ma si parla per lo più si vuole fare un appezzamento di picco rispetto l'anno, così si potrebbe anche semplicemente usare qplot:

A <- read.table("example.txt",header=TRUE)
library(ggplot2)
qplot(peak,year,data=A,colour=site,geom="line",group=site)
ggsave("peak-year-comparison.png")

alt text

D'altra parte, mi piace la soluzione di David Smith, che permette l'applicazione della funzione da eseguire su più processori.

Altri suggerimenti

È possibile utilizzare isplit (dal pacchetto "iteratori") per creare un oggetto iteratore che loop sopra i blocchi definiti dalla colonna site:

require(iterators)
site.data <- read.table("isplit-data.txt",header=T) 
sites <- isplit(site.data,site.data$site)

Quindi è possibile utilizzare foreach (dal pacchetto "foreach") per creare un grafico all'interno di ogni blocco:

require(foreach)
foreach(site=sites) %dopar% {
 pdf(paste(site$key[[1]],".pdf",sep=""))
 plot(site$value$year,site$value$peak,main=site$key[[1]])
 dev.off()
}

Come bonus, se si dispone di una macchina multiprocessore e chiamare registerDoMC() prima (dal pacchetto "domc"), i loop verrà eseguito in parallelo, accelerando le cose. Maggiori dettagli in questo post del blog Rivoluzioni: Block -Lavorazione un frame di dati con isplit

Mi sembra di ricordare che il buon vecchio split() ha un metodo per data.frames, in modo che split(data,data$site) produrrebbe una lista dei blocchi. Si potrebbe quindi operare su questo elenco utilizzando sapply / lapply / for.

split() è anche bello a causa di unsplit(), che creerà un vettore della stessa lunghezza dei dati originali e nell'ordine corretto.

Ecco cosa farei, anche se sembra che voi ragazzi avete li consegni funzioni di libreria.

for(i in 1:length(unique(data$site))){
  constrainedData = data[data$site==data$site[i]];
  doSomething(constrainedData);
}

Questo tipo di codice è più diretto e potrebbe essere meno efficiente, ma preferisco essere in grado di leggere quello che sta facendo di imparare qualche nuova funzione di libreria per la stessa cosa. rende questo sentire più flessibile anche, ma in tutta onestà questo è solo il modo in cui ho capito come novizio.

Ci sono due a portata di mano costruito nelle funzioni per affrontare questo tipo di situazioni. ? Aggregata e? By. In questo caso, perché si vuole una trama e non stanno tornando uno scalare, usa da ()

data <- read.table("example.txt",header=TRUE)

by(data[, c('year', 'peak')], data$site, plot)

L'output dice NULL perché è quello che ritorna trama. Si potrebbe desiderare di impostare il dispositivo grafico in pdf per catturare tutta l'uscita.

E 'anche molto facile da generare i diagrammi con il pacchetto reticolo:

library(lattice)
xyplot(year~peak | site, data)

È possibile utilizzare la funzione split Se avete aperto i vostri dati come:

data <- read.table('your_data.txt', header=T)
blocks <- split(data, data$site)

Dopo di che, i blocchi contiene i dati di ogni blocco, che è possibile accedere come altri data.frame:

plot(blocks$ALBEN$year, blocks$ALBEN$peak)

E così via per ogni lotto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top