R недельное усреднение

У меня есть набор дневных значений температуры поверхности моря с координатной сеткой за 34 года (12418 дневных файлов x 4248 точек), и я делаю вид, что рассчитываю еженедельные значения. Мне почти удалось подписаться на этот пост https://stackoverflow.com/a/15102394/709777. Но есть некоторые расхождения между датами и неделями. Я не могу понять суть и хочу быть уверенным, что получаю правильные даты для расчета среднего значения за неделю.

Я использую этот фрагмент моего сценария R для чтения ежедневных данных и создания большого фрейма данных, который содержит все дневные значения из одной точки в столбце (12418 строк / дней на 4248 столбцов / температура).

# Paths
ruta_datos_diarios<-"/home/meteo/PROJECTES/VERSUS/DATA/SST/CSV/"
ruta_files<-"/home/meteo/PROJECTES/VERSUS/SCRIPTS/CLUSTER/FILES/"
ruta_eixida<-"/home/meteo/PROJECTES/VERSUS/OUTPUT/DATA/SEMANAL/"

# List of daily files
files <- list.files(path = ruta_datos_diarios, pattern = "SST-diaria-MED")

output <- matrix(ncol=4248, nrow=length(files))
fechas <- matrix(ncol=1, nrow=length(files))

for (i in 1:length(files)){
  # read data
  datos<-read.csv(paste0(ruta_datos_diarios,files[i],sep=""),header=TRUE,na.strings = "NA")
  datos<-datos[complete.cases(datos),]

  # Extract dates from daily file names
  yyyy<-substr(files[i],16,19)
  mm<-substr(files[i],20,21)
  dd<-substr(files[i],22,23)
  dates[i,]<-paste0(yyyy,"-",mm,"-",dd,sep="")

  output[i,]<-t(datos$sst)
}

datos.df<-as.data.frame(output)

# Build a dataframe with the dates  (day, week and year)
fechas<-as.data.frame(fechas)
fechas$V1<-as.Date(fechas$V1)
fechas$Week <- week(fechas$V1)
fechas$Year <- year(fechas$V1)

# Extract day of the week (Saturday = 6)
fechas$Week_Day <- as.numeric(format(fechas$V1, format='%w'))
# Adjust end-of-week date (first saturday from the original Date)
fechas$End_of_Week <- fechas$V1 + (6 - fechas$Week_Day)

# new dataframe from End_of_Week
fechas.semana<-fechas[!duplicated(fechas$End_of_Week),]
fechas.semana<-as.data.frame(fechas.semana)

colnames(fechas)<-c("Day","Week","Year","Week_Day","End_of_Week")
colnames(fechas.semana)<-c("Day","Week","Year","Week_Day","End_of_Week")

Вот как я читаю свои данные и даты. В качестве краткого примера я сохранил подмножество фрейма данных в этом файле temp-sst.csv (1000 наблюдений из 10 переменных, включая« День »,« Неделя »,« Год »,« День_ недели »,« Конец_ недели »).

sst.dat <- read.csv("temp-dat.csv",header=TRUE)

# Join dates and SST values
sst.dat <- cbind(fechas, sst.dat)

# Build new dates data frame
fechas<-as.data.frame(sst.dat$Day)
colnames(fechas)<-c("Day")
fechas$Day<-as.Date(fechas$Day)
fechas$Week <- week(fechas$Day)
fechas$Year <- year(fechas$Day)
# Extract day of the week (Saturday = 6)
fechas$Week_Day <- as.numeric(format(fechas$Day, format='%w'))
# Adjust end-of-week date (first saturday from the original Date)
fechas$End_of_Week <- fechas$Day + (6 - fechas$Week_Day)

fechas.semana<-fechas[!duplicated(fechas$End_of_Week),]
fechas.semana<-as.data.frame(fechas.semana)

colnames(fechas)<-c("Day","Week","Year","Week_Day","End_of_Week")
colnames(fechas.semana)<-c("Day","Week","Year","Week_Day","End_of_Week")

# Weekly aggregation function from the referred post
media.semanal <- function(x, column){
  a<-aggregate(x[,column]~End_of_Week+Year, FUN=mean, data=x, na.rm=TRUE)
  colnames(a)<-c("End_of_Week","Year","SSTmean")
  return(a)
}

# Matrix to be populated by weekly function
SST.mat<-matrix(nrow=nrow(fechas.semana), ncol=length(sst.dat)-5)  # 5 son las columnas de fecha

for (j in 6:length(sst.dat)){   # comienza en 6 para evitar las columnas de fecha
b<-media.semanal(sst.dat,j)
SST.mat[,j-5]<-b$SSTmean
}

Но здесь возникает проблема. Фрейм данных "b" из цикла имеет 145 строк, в то время как SST.mat и fechas.semana - только 144. Я не нашел точки, где возникает это несогласие.

Любая помощь будет принята с благодарностью, я застрял здесь. Спасибо


person pacomet    schedule 02.12.2016    source источник
comment
В качестве краткого примера - вместо того, чтобы размещать ссылку на файл размером 1000 * 10 в Dropbox, вы должны предоставить минимальный автономный пример.   -  person Henrik    schedule 02.12.2016
comment
Вы правы @henrik, полезный флаг поднят   -  person pacomet    schedule 04.12.2016


Ответы (1)


У вас есть дубликат в одной долине b$End_of_Week.

Сначала я заметил, что разницы в составе набора нет:

setdiff(as.character(b$End_of_Week),as.character(fechas.semana$End_of_Week))

персонаж (0)

Затем я понял, что это должно быть из-за дубликата, и подтвердил это так:

table(table(as.character(b$End_of_Week))>1)
143    1 
FALSE  TRUE

Глядя на таблицу, видно, что обман - 1983-01-01.

Похоже, основная причина в том, что вы объединяете по End_of_Week + Year, где Year не требуется, поскольку в End_of_Week также указан год, и если вы объединяете только по End_of_Week, вы получаете 144 вместо 145.

# Weekly aggregation function from the referred post
media.semanal <- function(x, column){
  a<-aggregate(x[,column]~End_of_Week, FUN=mean, data=x, na.rm=TRUE)
  colnames(a)<-c("End_of_Week","SSTmean")
  return(a)
}

# Matrix to be populated by weekly function
SST.mat<-matrix(nrow=nrow(fechas.semana), ncol=length(sst.dat)-5)  # 5 son las columnas de fecha

for (j in 6:length(sst.dat)){   # comienza en 6 para evitar las columnas de fecha
  b<-media.semanal(sst.dat,j)
  SST.mat[,j-5]<-b$SSTmean
}
dim(b)

144 2

person Hack-R    schedule 02.12.2016