2009-09-08 3 views
10

Ich habe einen Datenrahmen mit mehreren Spalten, von denen eine ist ein Faktor namens "Site". Wie kann ich den Datenrahmen in Blöcke von Zeilen mit jeweils einem eindeutigen Wert von "site" aufteilen und dann jeden Block mit einer Funktion verarbeiten? Die Daten sehen wie folgt aus:Wie teilt man einen Datenrahmen nach Zeilen auf und verarbeitet dann die Blöcke?

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 

und ich möchte ein Grundstück von year vs peak für jede Website erstellen.

Antwort

12

Eine andere Wahl ist die ddply Funktion aus der ggplot2 Bibliothek. Aber Sie erwähnen Sie meist ein Grundstück von Spitzen vs. Jahr tun wollen, so können Sie auch nur qplot verwenden:

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 http://i32.tinypic.com/16nuza.png

Auf der anderen Seite, ich mag David Smith-Lösung, ermöglicht es dem Anwenden der Funktion, die über mehrere Prozessoren hinweg ausgeführt werden soll.

14

können Sie isplit verwenden (aus dem „Iteratoren“ -Paket) ein Iterator-Objekt zu erstellen, die die Blöcke Schleifen über die site Spalte definiert:

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

Dann können Sie foreach verwenden (von der „foreach“ Paket) ein Grundstück in jedem Block zu erstellen:

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() 
} 

Als Bonus, wenn Sie eine Multi-Prozessor-Maschine haben und rufen registerDoMC() ersten (von dem „domc“ -Paket), die Schleifen parallel ausgeführt werden, spe Dinge verbessern. Weitere Details in diesem Revolutions Blogbeitrag: Block-processing a data frame with isplit

4

Es gibt zwei praktische integrierte Funktionen für diese Art von Situationen. Aggregat und? In diesem Fall, da wollen Sie ein Grundstück und keinen Skalar, Verwendung von()

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

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

Die Ausgabe sagt NULL, weil das ist, was Handlung kehrt zurück. Möglicherweise möchten Sie das Grafikgerät auf PDF festlegen, um die gesamte Ausgabe zu erfassen.

6

Hier ist, was ich tun würde, obwohl es aussieht, wie Sie es von Bibliotheksfunktionen behandelt haben.

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

Diese Art von Code ist direkter und vielleicht weniger effizient sein, aber ich ziehe es lesen zu können, was es einige neue Bibliotheksfunktion für die gleiche Sache als lernen tut. macht es auch flexibler, aber ehrlich gesagt, das ist nur die Art und Weise, wie ich es als Anfänger herausgefunden habe.

+1

Karl, ich stimme zu, dass dies lesbar ist. Aber der Code zum Plotten ('doSomething') wäre viel weniger. Gute Lösung für ein anderes Problem imho. – isomorphismes

10

Ich erinnere mich, dass plain alt split() hat eine Methode für data.frames, so dass split(data,data$site) würde eine Liste von Blöcken zu erzeugen. Sie könnten dann auf dieser Liste mit sapply/lapply/for arbeiten.

split() ist auch nett wegen unsplit(), die einen Vektor die gleiche Länge wie die ursprünglichen Daten und in der richtigen Reihenfolge erstellen wird.

2

Es ist auch sehr einfach, Ihre Plots mit dem Gitter-Paket zu generieren:

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

Sie die split Funktion nutzen könnten Wenn Sie Ihre Daten geöffnet:

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

Danach blockiert enthält Daten von jedem Block, auf den Sie als andere Daten zugreifen können.frame:

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

Und so weiter für jedes Grundstück.

Verwandte Themen