2017-11-15 12 views
0

Ich habe 73 netCDF-Dateien, die jeweils 5-Tages-Intervalle eines Kalenderjahres repräsentieren und mehrere Variablen haben. Jede Datei hat 120 Schichten, die stündliche Intervalle darstellen.Wie man eine Funktion mit einer spezifischen netCDF-Datei basierend auf dem Zeitstempel verbindet

Ich habe sie alle in R lesen und benannte sie in geeigneter Weise mit dem ncdf4 Paket wie folgt:

filenames <- list.files(path=getwd()) 

for(i in filenames) { 
    ncin <- nc_open(i) 
    ds<-paste(i) 
    assign(ds, ncin) 
    print(i) 
    } 

ich auch einen Datenrahmen von Standorten in der gleichen Projektion wie die netCDF-Dateien haben (lat-lon) Allerdings erstrecken sich diese Standorte unregelmäßig auch über das gesamte Kalenderjahr. Eine Probe der Daten sieht wie folgt aus:

>head(df) 
> Lon  Lat   datetime 
2 -3.179046 58.65417 2016-09-30 17:25:38 
3 -3.180403 58.65483 2016-09-30 17:29:43 
4 -3.187734 58.66102 2016-09-30 21:22:51 
5 -3.190197 58.66409 2016-09-30 22:02:47 
6 -3.182058 58.67433 2016-10-01 06:16:08 
7 -3.181318 58.67475 2016-10-01 06:20:31 

Was ich versuche, ist also Datetime-Stempel auf der Grundlage zu tun ist, um den Daten-Rahmen auf die richtigen netCDF-Datei und Schicht übereinstimmen, wenn es zwischen Tag 1 und 5 das Jahr wäre netCDF Datei 1 usw .. dann möchte ich die variablen Daten aus der netCDF Datei auf die Standortdaten mit zugehörigem Datum-Zeit-Stempel des Datenrahmens interpolieren. Also zu der gegebenen Zeit und Stelle, die durch den Datenrahmen bereitgestellt wird, was ist der Wert der Variablen V zum selben Datum und derselben Zeit in der netCDF-Datei. Ich kann den ersten Teil mit Loop-Funktionen zu tun, aber es ist höchst ineffizient und zeitraubend Code:

function(dataframe){ 
d <- dataframe[i,] 
if(between(d$datetime, 2017-01-01 00:00:00, 2017-01-05 23:59:59){ncfile <- file1} else if (between(d$datetime, 2017-01-06 00:00:00, 2017-01-010 23:59:59)) 
    {ncfile <- file2}} 

Und so weiter ... Da ich noch nie mit netCDF-Dateien gearbeitet, bevor ich in Bezug auf die beste Methode nicht sicher bin. Irgendwelche Vorschläge?

################# UPDATE

las ich die netCDF-Dateien in mit

filenames <- list.files(path=getwd()) 
x <- lapply(filenames, nc_open) 

Extrakt stammt aus der Datei, die nacheinander benannt sind:

PFOW_Climatology2_0001_1993-01-01.nc 
PFOW_Climatology2_0002_1993-01-06.nc 

bis zu

PFOW_Climatology2_0073_1993-12-27.nc 

unter Verwendung

fd <- as.Date(substr(filenames, 24, 36)) 

ich das Intervall eine Referenzspalte für die Datenrahmen erstellen dann innerhalb derer von find9ing jeder Datenpunkt wie so in fd entspricht:

i <- findInterval(dd, fd) 
df$file <- i 

Antwort

1

Es ist sehr schwierig, eine gute Antwort zu geben, ohne dass Sie mehr bieten Informationen und idealerweise einige Beispieldaten.

Ihre "angemessene Benennung" ist höchst unangemessen. Sie sollten wirklich assign im täglichen Leben nicht brauchen. Mach einfach eine Liste.

library(ncdf4) 
x <- lapply(filenames, nc_open) 

Aber da Sie Wert nach Ort extrahieren müssen, ist es vielleicht besser, eine Liste von RasterBrick Objekten zu machen:

library(raster) 
x <- lapply(filenames, brick) 

Aber ich würde das auch nicht.

Ich würde zuerst die Dateinamen mit df $ datetime übereinstimmen. Da Sie uns nicht sagen, wie die Dateinamen aussehen, kann ich Ihnen nicht sagen, wie das geht. Aber Sie brauchen keine Schleife. Extrahiere die Daten aus den Dateinamen, erstelle ein passendes Datum (und Zeit?) Objekt und etwas tun, wie

fd <- as.Date(subtr(filenames, 4, 12)) 
dd <- as.Date(df$datetime) 
i <- which(dd > fd[-length(fd)] & dd < fd[-1]) + 1 

df$file <- filenames[i] 
df$id <- 1:nrow(df) 

Jetzt können Sie Schleife über die Dateinamen und die Werte extrahieren:

ff <- unique(df$file) 
vv <- sapply(ff, function(f) { 
     v <- extract(brick(f), df[df$file == f , c('lon', 'lat')]) 
     data.frame(file=f, xy, v) 
     }) 

vv ein data.frame mit Werten für jeden Fall sein sollte, für seine entsprechenden 5- Tagesintervall. Wählen Sie die gewünschte Zeit aus den 120 Werten aus (oder interpolieren Sie sie).

Ich nehme an, dass Sie zeitliche Interpolation tun möchten. Für (auch) räumliche Interpolation verwenden Sie in extract

Auch dies funktioniert möglicherweise nicht, da ich keine Beispieldaten habe. Aber etwas in dieser Richtung wird funktionieren.

+0

Vielen Dank @RobertH. Ich habe die Frage so geändert, dass sie mehr Informationen enthält und aktualisiert wurde, um die neuesten Vorschläge einzubeziehen, die Sie sehr hilfreich fanden. Ich konnte Ihre {what} Funktion nicht verwenden, also habe ich stattdessen 'findInterval' verwendet. –

+0

Ich bin mir aber nicht sicher wie deine Funktion funktionieren soll. Wenn Sie versuchen, ein ncdf4-Objekt zu erstellen, erhalten Sie einen Fehler: 'eine geerbte Methode für die Funktion' raster 'für die Signatur konnte nicht gefunden werden' 'ncdf4' ' –

+0

'brick' sollte für den Dateinamen verwendet werden, nicht für ein ncdf4-Objekt – RobertH

Verwandte Themen