2009-09-08 13 views
10

Tengo un marco de datos con varias columnas, una de las cuales es un factor llamado "sitio". ¿Cómo puedo dividir el marco de datos en bloques de filas, cada uno con un valor único de "sitio", y luego procesar cada bloque con una función? Los datos de este aspecto:¿Cómo dividir un marco de datos por filas y luego procesar los bloques?

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 

y quiero crear una parcela de year vs peak para cada sitio.

Respuesta

12

Otra opción es utilizar la función de la biblioteca ddplyggplot2. Sin embargo, menciona que la mayoría quiere hacer una parcela de pico respecto al año, por lo que también podría simplemente utilizar 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

Por otro lado, me gusta la solución de David Smith que permite la aplicación de la función que se ejecutará en varios procesadores.

14

Usted puede utilizar isplit (del paquete "iteradores") para crear un objeto iterador que se repite en los bloques definidos por la columna de site:

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

continuación, puede utilizar foreach (desde la "foreach" paquete) para crear una trama dentro de cada bloque:

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

Como beneficio adicional, si usted tiene una máquina multiprocesador y llamar registerDoMC() primera (del paquete "DOMC"), los bucles se ejecutarán en paralelo, spe arreglando las cosas. Más detalles en esta entrada del blog: Revoluciones Block-processing a data frame with isplit

4

Existen dos prácticas funciones integradas para tratar este tipo de situaciones. ? agregado y? por. En este caso, ya que desea un argumento y no devuelve un escalar, el uso de()

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

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

La salida dice NULL porque eso es lo que vuelve la trama. Es posible que desee configurar el dispositivo gráfico en pdf para capturar todo el resultado.

6

Esto es lo que yo haría, aunque parece que ustedes lo tienen manejado por las funciones de la biblioteca.

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

Este tipo de código es más directo y podría ser menos eficiente, pero prefiero ser capaz de leer lo que está haciendo que aprender alguna nueva función de biblioteca para la misma cosa. hace que esto se sienta más flexible también, pero honestamente, esta es la forma en que lo descubrí como novato.

+1

Karl, estoy de acuerdo en que esto es legible. Pero el código para trazar ('doSomething') sería mucho menos. Buena solución para un problema diferente. – isomorphismes

10

Me parece recordar que el antiguo split() tiene un método para data.frames, por lo que split(data,data$site) produciría una lista de bloques. Luego puede operar en esta lista usando sapply/lapply/for.

split() también es bueno debido a unsplit(), que creará un vector de la misma longitud que los datos originales y en el orden correcto.

2

También es muy fácil de generar sus parcelas con el paquete de celosía:

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

usted podría utilizar la función split Si ha abierto sus datos como:

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

Después de eso, los bloques contiene datos de cada bloque, a los que se puede acceder como otros data.frame:

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

Y así sucesivamente para cada parcela.

Cuestiones relacionadas