2011-03-28 12 views
5

Siguiendo con mi previous question sobre la agregación de datos por hora en datos diarios, deseo continuar con (a) agregado mensual y (b) fusionar el agregado mensual en el marco de datos original.Fusionando datos agregados en R

Mi trama de datos original están presentes:

Lines <- "Date,Outdoor,Indoor 
01/01/2000 01:00,30,25 
01/01/2000 02:00,31,26 
01/01/2000 03:00,33,24 
02/01/2000 01:00,29,25 
02/01/2000 02:00,27,26 
02/01/2000 03:00,39,24 
12/01/2000 02:00,27,26 
12/01/2000 03:00,39,24 
12/31/2000 23:00,28,25" 

Los agregados diarios han sido respondidas en mi previous question, y luego puedo encontrar mi manera de producir los agregados mensuales desde allí, a algo como esto:

Lines <- "Date,Month,OutdoorAVE 
01/01/2000,Jan,31.33 
02/01/2000,Feb,31.67 
12/01/2000,Dec,31.33" 

Donde OutdoorAVE es el promedio mensual de la temperatura diaria mínima y máxima al aire libre. Lo que quiero tener al final es algo como esto:

Lines <- "Date,Outdoor,Indoor,Month,OutdoorAVE 
01/01/2000 01:00,30,25,Jan,31.33 
01/01/2000 02:00,31,26,Jan,31.33 
01/01/2000 03:00,33,24,Jan,31.33 
02/01/2000 01:00,29,25,Feb,31.67 
02/01/2000 02:00,27,26,Feb,31.67 
02/01/2000 03:00,39,24,Feb,31.67 
12/01/2000 02:00,27,26,Dec,31.33 
12/01/2000 03:00,39,24,Dec,31.33 
12/31/2000 23:00,28,25,Dec,31.33" 

No sé suficiente R sobre cómo hacerlo. Cualquier ayuda es muy apreciada.

Respuesta

2

Trate ave y, por ejemplo POSIXlt para extraer el mes:

zz <- textConnection(Lines) 
Data <- read.table(zz,header=T,sep=",",stringsAsFactors=F) 
close(zz) 

Data$Month <- strftime(
    as.POSIXlt(Data$Date,format="%m/%d/%Y %H:%M"), 
    format='%b') 
Data$outdoor_ave <- ave(Data$Outdoor,Data$Month,FUN=mean) 

Da:

> Data 
       Date Outdoor Indoor Month outdoor_ave 
1 01/01/2000 01:00  30  25 Jan 31.33333 
2 01/01/2000 02:00  31  26 Jan 31.33333 
3 01/01/2000 03:00  33  24 Jan 31.33333 
4 02/01/2000 01:00  29  25 Feb 31.66667 
5 02/01/2000 02:00  27  26 Feb 31.66667 
6 02/01/2000 03:00  39  24 Feb 31.66667 
7 12/01/2000 02:00  27  26 Dec 31.33333 
8 12/01/2000 03:00  39  24 Dec 31.33333 
9 12/31/2000 23:00  28  25 Dec 31.33333 

Editar: A continuación, sólo Mes calcualte de datos como se muestra arriba y utilizar la combinación de:

zz <- textConnection(Lines2) # Lines2 is the aggregated data 
Data2 <- read.table(zz,header=T,sep=",",stringsAsFactors=F) 
close(zz) 

> merge(Data,Data2[-1],all=T) 
    Month    Date Outdoor Indoor OutdoorAVE 
1 Dec 12/01/2000 02:00  27  26  31.33 
2 Dec 12/01/2000 03:00  39  24  31.33 
3 Dec 12/31/2000 23:00  28  25  31.33 
4 Feb 02/01/2000 01:00  29  25  31.67 
5 Feb 02/01/2000 02:00  27  26  31.67 
6 Feb 02/01/2000 03:00  39  24  31.67 
7 Jan 01/01/2000 01:00  30  25  31.33 
8 Jan 01/01/2000 02:00  31  26  31.33 
9 Jan 01/01/2000 03:00  33  24  31.33 
+0

@Joris Meys: Mi problema es que outdoorAVE está en otro marco de datos (por ejemplo, Data.Month) que tiene solo el mes y las columnas promedio, y solo hay 12 filas de este por un año. El exteriorAVE no se calcula como se escribe arriba, sino de los agregados (diarios y mensuales) de los datos anuales por hora. Entonces, lo que quiero es agregar una columna en el marco de datos original (es decir, datos en el ejemplo anterior) donde la columna se toma de otro conjunto de datos (por ejemplo, Data.Monthly). – ery

+0

@ery: edité mi respuesta para mostrarle cómo usar merge –

+0

@ery: en su comentario, usted dice 'Data.Monthly' solo tiene 2 columnas (mes y promedio), pero tiene 3 columnas en su pregunta original. –

0

Aquí hay una solución zoo/xts. Tenga en cuenta que Month es numérico aquí porque no puede mezclar tipos en objetos zoo/xts.

require(xts) # loads zoo too 
Lines1 <- "Date,Outdoor,Indoor 
01/01/2000 01:00,30,25 
01/01/2000 02:00,31,26 
01/01/2000 03:00,33,24 
02/01/2000 01:00,29,25 
02/01/2000 02:00,27,26 
02/01/2000 03:00,39,24 
12/01/2000 02:00,27,26 
12/01/2000 03:00,39,24 
12/31/2000 23:00,28,25" 
con <- textConnection(Lines1) 
z <- read.zoo(con, header=TRUE, sep=",", 
    format="%m/%d/%Y %H:%M", FUN=as.POSIXct) 
close(con) 

zz <- merge(z, Month=.indexmon(z), 
    OutdoorAVE=ave(z[,1], .indexmon(z), FUN=mean)) 
zz 
#      Outdoor Indoor Month OutdoorAVE 
# 2000-01-01 01:00:00  30  25  0 31.33333 
# 2000-01-01 02:00:00  31  26  0 31.33333 
# 2000-01-01 03:00:00  33  24  0 31.33333 
# 2000-02-01 01:00:00  29  25  1 31.66667 
# 2000-02-01 02:00:00  27  26  1 31.66667 
# 2000-02-01 03:00:00  39  24  1 31.66667 
# 2000-12-01 02:00:00  27  26 11 31.33333 
# 2000-12-01 03:00:00  39  24 11 31.33333 
# 2000-12-31 23:00:00  28  25 11 31.33333 

Actualización: ¿Cómo se obtiene el resultado anterior utilizando dos conjuntos de datos diferentes.

Lines2 <- "Date,Month,OutdoorAVE 
01/01/2000,Jan,31.33 
02/01/2000,Feb,31.67 
12/01/2000,Dec,31.33" 
con <- textConnection(Lines2) 
z2 <- read.zoo(con, header=TRUE, sep=",", format="%m/%d/%Y", 
    FUN=as.POSIXct, colClasses=c("character","NULL","numeric")) 
close(con) 

zz2 <- na.locf(merge(z1, Month=.indexmon(z1), OutdoorAVE=z2))[index(z1)] 
# same output as zz (above) 
+0

Intenté esto, pero el mes siempre es 11 para todo el año. – ery

+0

@ery: por favor, mira mi edición. No estoy seguro de por qué Month siempre tendrá 11 ... tal vez sus datos de ejemplo y datos reales difieren? –

2

Ésta es tangencial a su pregunta, pero es posible que desee utilizar un RSQLite y tablas separadas para diferentes valores agregados en su lugar, y unirse a las tablas con simples comandos SQL. Si usa muchos tipos de agregaciones, su marco de datos puede volverse grande y feo.

+0

Esta es una buena solución, pero ni siquiera sé cómo importar la fecha/hora en SQLite, y mucho menos agruparla por mes o por día. ¿Alguna ayuda? – ery

+1

Todo su problema se puede resolver en SQL. No digo que deba usar SQL para la agregación, pero es útil saber cómo funciona (bastante fácil). Sugiero que leas un poco y hagas tus preguntas en hilos separados. – GaBorgulya

Cuestiones relacionadas