2009-09-08 15 views
10

Mam ramkę danych z kilkoma kolumnami, z których jedna jest czynnikiem o nazwie "witryna". Jak podzielić ramkę danych na bloki wierszy, z których każda ma unikalną wartość "witryny", a następnie przetworzyć każdy blok za pomocą funkcji? Dane wyglądać następująco:Jak podzielić ramkę danych według wierszy, a następnie przetworzyć bloki?

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 

i chcę stworzyć wykres year vs peak dla każdej witryny.

Odpowiedz

12

Kolejnym wyborem jest użycie funkcji ddply z biblioteki ggplot2. Ale wspomina pan głównie chcą zrobić wykres szczyt vs. roku, więc można też po prostu użyć 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 http://i32.tinypic.com/16nuza.png

Z drugiej strony, lubię rozwiązania Davida Smitha, który pozwala zastosowanie funkcji, która ma zostać uruchomiona w kilku procesorach.

14

Można użyć isplit (z pakietu „iteratory”), aby utworzyć obiekt iteracyjnej że pętle ciągu bloków zdefiniowanych przez kolumnę site:

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

Następnie można użyć foreach (od „foreach” pakiet), aby utworzyć wykres w każdym bloku:

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

Jako bonus, jeśli masz maszynę wieloprocesorowych i nazywają registerDoMC() pierwszy (z pakietu „doMC”), pętle będą działać równolegle, spe poprawianie rzeczy. Więcej szczegółów na ten temat w blogu Revolutions: Block-processing a data frame with isplit

4

Dostępne są dwie przydatne funkcje do radzenia sobie z takimi sytuacjami. ? agregacja i? przez. W tym przypadku, ponieważ chcesz działkę i nie wracają skalarną użytkowego przez()

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

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

Wyjście mówi NULL bo to właśnie powraca wydruku. Możesz ustawić urządzenie graficzne na pdf, aby uchwycić wszystkie dane wyjściowe.

6

Oto, co chciałbym zrobić, chociaż wygląda na to, że zajmują się nim funkcje biblioteczne.

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

Taki kod jest bardziej bezpośredni i może być mniej skuteczny, ale wolę być w stanie odczytać, co robi, niż uczyć się nowych funkcji biblioteki dla tej samej rzeczy. sprawia, że ​​czuję się bardziej elastyczna, ale szczerze mówiąc, to jest właśnie sposób, w jaki określiłem to jako nowicjusz.

+1

Karl, zgadzam się, że to jest czytelne. Ale kod do rysowania ('doSomething') byłby znacznie mniejszy. Dobre rozwiązanie dla innego problemu imho. – isomorphismes

10

Przypominam sobie, że zwykły stary split() ma metodę dla data.frames, dzięki czemu split(data,data$site) wyświetli listę bloków. Następnie można operować na tej liście, używając sapply/lapply/for.

split() jest również ładny ze względu na unsplit(), który utworzy wektor o tej samej długości co oryginalne dane i we właściwej kolejności.

2

Jest również bardzo łatwy do generowania wykresów z pakietem siatkowej:

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

można użyć split funkcję Jeśli otworzył swoje dane jak:

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

Po tym, bloków zawiera dane z każdego bloku, do których można uzyskać dostęp jako inne dane.frame:

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

itd. Dla każdej działki.

Powiązane problemy