library(spacetime)
library(gstat)
library(tidyverse)
library(sf)Dane czasoprzestrzenne w R. Część 1
1 Dane czasoprzestrzenne
Dane czasoprzestrzenne (ang. spatio-temporal data) to obserwacje, dla których zarejestrowano jednocześnie lokalizację przestrzenną , czas obserwacji oraz atrybuty (wartości analizowanej cechy) zmierzone w tym konkretnym miejscu i momencie czasu.
Struktura danych czasoprzestrzennych obejmuje 3 wymiary:
Przestrzeń (Space): Informacja o lokalizacji i układzie współrzędnych (CRS), np. klasa SpatialPoints
Czas (Time): Indeks czasowy określający datę lub moment pomiaru, często reprezentowany jako klasa POSIXct lub xts
Atrybuty (Attributes): Mierzone parametry zjawiska, np. stężenie pyłu PM10 czy prędkość wiatru.
2 Dane czasoprzestrzenne w R
W środowisku R dane czasoprzestrzenne są reprezentowane głównie poprzez system klas zdefiniowany w pakiecie spacetime, który integruje dane przestrzenne z pakietu sp oraz szeregi czasowe z pakietu xts. Klasy te pozwalają na jednoczesne przechowywanie geometrii (np. punktów, poligonów), indeksu czasu oraz mierzonych atrybutów. Pakiet spacetime dostarcza kilka klas obiektów.
| Klasa | Opis | Zastosowanie |
|---|---|---|
| STFDF (Full) | Każda lokalizacja ma przypisany pomiar w każdym punkcie czasu | Stacje meteorologiczne, dane satelitarne |
| STSDF (Sparse) | Tylko niektóre kombinacje miejsca i czasu mają przypisane dane | Monitoring mobilny (czujniki nie mają stałej lokalizacji) |
| STTDF (Trajectories) | Trajektorie: dane o ruchu, gdzie lokalizacja \(s\) jest bezpośrednią funkcją czasu \(t\). | Ślady GPS zwierząt, loty samolotów. |
W geostatystyce będziemy korzystać z klasy STFDF (ang. Space-Time Full-grid Data Frame). Klasa STF przechowuje wyłącznie geometrię, a klasa STFDF przechowuje także atrybuty pomiarów (dane).
2.1 Struktura obiektu STFDF
Klasa STFDF (ang. Space-Time Full-grid Data Frame) reprezentuje pełną siatkę czasoprzestrzenną, gdzie dla każdej lokalizacji przestrzennej przypisany jest pomiar w każdym punkcie czasu.
Obiekt STFDF składa się z czterech głównych pól (slotów):
@sp: Zawiera obiekt klasy Spatial (z pakietu sp), definiujący geometrię (np. SpatialPoints dla stacji pomiarowych lub SpatialPolygons dla jednostek administracyjnych) oraz układ współrzędnych (CRS).
@time: Przechowuje indeks czasowy w formacie klasy xts, co pozwala na elastyczne operacje na szeregach czasowych
@data: Ramka danych (data.frame) zawierająca atrybuty (zmienne mierzone) przypisane do konkretnych punktów w czasie i przestrzeni
@endTime: Wektor klasy POSIXct określający punkty końcowe interwałów czasowych, co pozwala na rozróżnienie między pomiarami natychmiastowymi a danymi zagregowanymi w czasie
2.2 Zrozumienie struktury obiektu STFDF
2.3 Tworzenie obiektu STFDF
Komponent przestrzenny
Utworzymy obiekt przestrzenny klasy SpatialPoints składający się z 3 punktów.
# Wczytanie bibliotek do operacji przestrzennych i czasoprzestrzennych
library(sp)
library(spacetime)
set.seed(123)
# --- KOMPONENT PRZESTRZENNY ---
# Tworzenie macierzy współrzędnych (3 punkty: [0,0], [0,1], [1,1])
sp = cbind(x = c(0,0,1), y = c(0,1,1))
# Przypisanie unikalnych nazw dla wierszy (lokalizacji)
row.names(sp) = paste("P", 1:nrow(sp), sep="")
# Konwersja zwykłej macierzy na obiekt klasy SpatialPoints
sp = SpatialPoints(sp)
spSpatialPoints:
x y
P1 0 0
P2 0 1
P3 1 1
Coordinate Reference System (CRS) arguments: NA
# Szybki podgląd rozmieszczenia punktów w przestrzeni
# Rysowanie punktów
plot(sp, pch = 19, cex = 2, col = "royalblue", main = "Lokalizacje punktów")
# Dodawanie etykiet
# coordinates(sp) - wyciąga macierz współrzędnych x i y
# labels - bierze nazwy wierszy, które wcześniej nadaliśmy (point1, point2, itd.)
# pos = 3 - umieszcza tekst NAD punktem (1=dół, 2=lewo, 3=góra, 4=prawo)
# offset = 0.5 - dodaje lekki odstęp między punktem a tekstem
text(coordinates(sp), labels = row.names(sp), pos = 2, cex = 1.1, col = "black")Komponent przestrzenny
Komponent czasowy składa się z 4 okresów w czasie - od godziny 10 do 13, co godzinę.
# --- KOMPONENT CZASOWY ---
# Utworzenie wektora 4 punktów czasowych (co godzinę, od 10:00 do 13:00)
# format POSIXct jest wymagany przez pakiet spacetime
czas = as.POSIXct("2025-08-05", tz = "GMT") + 3600*(10:13)
czas[1] "2025-08-05 10:00:00 GMT" "2025-08-05 11:00:00 GMT"
[3] "2025-08-05 12:00:00 GMT" "2025-08-05 13:00:00 GMT"
Komponent danych (atrybuty)
W punktach P1-P3 o godzinie 10, 11, 12, 13 zmierzono temperaturę powietrza. Dane te są przechowywane w obiekcie temp. Wiersze odpowiadają kolejnym lokalizacją, a kolumny kolejnym momentom w czasie.
temp = data.frame(T1 = c(9.44, 19.8, 31.6),
T2 = c(10.1, 20.1, 31.7),
T3 = c(10.5, 18.17, 29.3),
T4 = c(9.55, 21.20, 30.40))
rownames(temp) = c("P1", "P2", "P3")
temp T1 T2 T3 T4
P1 9.44 10.1 10.50 9.55
P2 19.80 20.1 18.17 21.20
P3 31.60 31.7 29.30 30.40
Przekształcimy dane na wektor. Należy zwrócić uwagę na kolejność punktów wartości. Najpierw występują wartości dla czasu T1 dla P1, P2, P3, następnie dla czasu T2 dla P1, P2, P3, itd.
wektor = unlist(as.vector(temp))
wektor T11 T12 T13 T21 T22 T23 T31 T32 T33 T41 T42 T43
9.44 19.80 31.60 10.10 20.10 31.70 10.50 18.17 29.30 9.55 21.20 30.40
Tworzymy komponent danych. Liczba wierszy = Liczba punktów * Liczba okresów czasu, czyli w przykładzie 3(P) * 4(T) = 12. Wartości muszą być najpierw posortowane wg czasu (T1:T4), a dla każdego momentu czasu wg obiektów przestrzennych (P1:P3). W poniższej tabeli ID T11 oznacza T1
dane <- data.frame(
Temp = wektor,
# T zmienia się co 1 (T1, T2, T3, T4, T1...)
ID = paste0(rep(c("T1", "T2", "T3", "T4"), each = 3),rep(c("P1", "P2", "P3"), times = 4))
# P powinno stać w miejscu przez 4 wiersze (P1, P1, P1, P1, P2...)
)
rownames(dane) = dane$ID
dane Temp ID
T1P1 9.44 T1P1
T1P2 19.80 T1P2
T1P3 31.60 T1P3
T2P1 10.10 T2P1
T2P2 20.10 T2P2
T2P3 31.70 T2P3
T3P1 10.50 T3P1
T3P2 18.17 T3P2
T3P3 29.30 T3P3
T4P1 9.55 T4P1
T4P2 21.20 T4P2
T4P3 30.40 T4P3
2.3.1 Konstrukcja obiektu STFDF
W obiekcie STFDF każdy punkt ma dane w każdym momencie czasu. Do konstrukcji obiektu możemy użyć funkcji STFDF() lub funkcji stConstruct()
# Tworzenie obiektu, gdzie czas traktowany jest jako momenty (punkty w czasie)
stfdf = STFDF(sp = sp, time = czas, data = dane)
# Sprawdzenie struktury gotowego obiektu
print(stfdf)An object of class "STFDF"
Slot "data":
Temp ID
T1P1 9.44 T1P1
T1P2 19.80 T1P2
T1P3 31.60 T1P3
T2P1 10.10 T2P1
T2P2 20.10 T2P2
T2P3 31.70 T2P3
T3P1 10.50 T3P1
T3P2 18.17 T3P2
T3P3 29.30 T3P3
T4P1 9.55 T4P1
T4P2 21.20 T4P2
T4P3 30.40 T4P3
Slot "sp":
SpatialPoints:
x y
P1 0 0
P2 0 1
P3 1 1
Coordinate Reference System (CRS) arguments: NA
Slot "time":
timeIndex
2025-08-05 10:00:00 1
2025-08-05 11:00:00 2
2025-08-05 12:00:00 3
2025-08-05 13:00:00 4
Slot "endTime":
[1] "2025-08-05 11:00:00 GMT" "2025-08-05 12:00:00 GMT"
[3] "2025-08-05 13:00:00 GMT" "2025-08-05 14:00:00 GMT"
2.3.2 Struktura obiektu STFDF
dim(stfdf) space time variables
3 4 2
str(stfdf)Formal class 'STFDF' [package "spacetime"] with 4 slots
..@ data :'data.frame': 12 obs. of 2 variables:
.. ..$ Temp: num [1:12] 9.44 19.8 31.6 10.1 20.1 ...
.. ..$ ID : chr [1:12] "T1P1" "T1P2" "T1P3" "T2P1" ...
..@ sp :Formal class 'SpatialPoints' [package "sp"] with 3 slots
.. .. ..@ coords : num [1:3, 1:2] 0 0 1 0 1 1
.. .. .. ..- attr(*, "dimnames")=List of 2
.. .. .. .. ..$ : chr [1:3] "P1" "P2" "P3"
.. .. .. .. ..$ : chr [1:2] "x" "y"
.. .. ..@ bbox : num [1:2, 1:2] 0 0 1 1
.. .. .. ..- attr(*, "dimnames")=List of 2
.. .. .. .. ..$ : chr [1:2] "x" "y"
.. .. .. .. ..$ : chr [1:2] "min" "max"
.. .. ..@ proj4string:Formal class 'CRS' [package "sp"] with 1 slot
.. .. .. .. ..@ projargs: chr NA
..@ time :An xts object on 2025-08-05 10:00:00 / 2025-08-05 13:00:00 containing:
Data: integer [4, 1]
Columns: timeIndex
Index: POSIXct,POSIXt [4] (TZ: "GMT")
..@ endTime: POSIXct[1:4], format: "2025-08-05 11:00:00" "2025-08-05 12:00:00" ...
Plik składa się z 4 slotów: data, sp, time oraz endTime. Aby odwołać się do konkretnego slotu używa się znaku @.
- Slot sp przechowuje obiekty przestrzenne typu SpatialPoints
stfdf@spSpatialPoints:
x y
P1 0 0
P2 0 1
P3 1 1
Coordinate Reference System (CRS) arguments: NA
plot(stfdf@sp, cex = 3, col = "red", pch = 20)- Slot sp przechowuje także informacje o zasięgu danych (bbox) oraz współrzędnych (coords).
stfdf@sp@bbox min max
x 0 1
y 0 1
stfdf@sp@coords x y
P1 0 0
P2 0 1
P3 1 1
- Slot time przechowuje informacje o momentach w czasie. W tym przypadku czas został zdefiniowany co godzinę od 10 do 13.00
stfdf@time timeIndex
2025-08-05 10:00:00 1
2025-08-05 11:00:00 2
2025-08-05 12:00:00 3
2025-08-05 13:00:00 4
- Slot data przechowuje informację o atrybutach
stfdf@data Temp ID
T1P1 9.44 T1P1
T1P2 19.80 T1P2
T1P3 31.60 T1P3
T2P1 10.10 T2P1
T2P2 20.10 T2P2
T2P3 31.70 T2P3
T3P1 10.50 T3P1
T3P2 18.17 T3P2
T3P3 29.30 T3P3
T4P1 9.55 T4P1
T4P2 21.20 T4P2
T4P3 30.40 T4P3
stfdf@data$Temp [1] 9.44 19.80 31.60 10.10 20.10 31.70 10.50 18.17 29.30 9.55 21.20 30.40
2.4 Selekcja
Obiekt klasy STFDF są obiektami trójwymiarowymi, których selekcję można wykonywać za pomocą [].
obj[space, time, attr, drop = TRUE]
- Wybór danych dla pierwszej lokalizacji P1
stfdf[1,] Temp ID timeIndex
2025-08-05 10:00:00 9.44 T1P1 1
2025-08-05 11:00:00 10.10 T2P1 2
2025-08-05 12:00:00 10.50 T3P1 3
2025-08-05 13:00:00 9.55 T4P1 4
dim(stfdf[1,])[1] 4 3
- Wybór danych dla momentu w czasie 2 i 3 (godzina 11 i 12)
stfdf[, 2:3]An object of class "STFDF"
Slot "data":
Temp ID
1 10.10 T2P1
2 20.10 T2P2
3 31.70 T2P3
4 10.50 T3P1
5 18.17 T3P2
6 29.30 T3P3
Slot "sp":
SpatialPoints:
x y
P1 0 0
P2 0 1
P3 1 1
Coordinate Reference System (CRS) arguments: NA
Slot "time":
timeIndex
2025-08-05 11:00:00 2
2025-08-05 12:00:00 3
Slot "endTime":
[1] "2025-08-05 12:00:00 GMT" "2025-08-05 13:00:00 GMT"
dim(stfdf[, 2:3]) space time variables
3 2 2
Po selekcji nadal mapy 3 punkty, 2 zmienne ale dane zostały ograniczone tylko do godziny 11.00 i 12.00.
stfdf[, , "Temp"]An object of class "STFDF"
Slot "data":
Temp
1 9.44
2 19.80
3 31.60
4 10.10
5 20.10
6 31.70
7 10.50
8 18.17
9 29.30
10 9.55
11 21.20
12 30.40
Slot "sp":
SpatialPoints:
x y
P1 0 0
P2 0 1
P3 1 1
Coordinate Reference System (CRS) arguments: NA
Slot "time":
timeIndex
2025-08-05 10:00:00 1
2025-08-05 11:00:00 2
2025-08-05 12:00:00 3
2025-08-05 13:00:00 4
Slot "endTime":
[1] "2025-08-05 11:00:00 GMT" "2025-08-05 12:00:00 GMT"
[3] "2025-08-05 13:00:00 GMT" "2025-08-05 14:00:00 GMT"
dim(stfdf[, , "Temp"]) space time variables
3 4 1
- Wybór zmiennej Temp dla punktu P1 dla godzin 11 i 12.
stfdf[1, 2:3 , "Temp"] Temp timeIndex
2025-08-05 11:00:00 10.1 2
2025-08-05 12:00:00 10.5 3
Wybierz dane dla godziny 13, dla punktu P3. Ile wynosiła temperatura w punkcie P3 o godzinie 13.00?
3 Wizualizacja
Do wizualizacji danych wykorzystuje się funkcję stplot(). Przy ustawieniach domyślnych zostaną wyświetlone panele dla każdego momentu w czasie pokazujące rozkład wartości zmierzonych w lokalizacjach.
stplot(stfdf)3.1 Diagram Hovmollera,
Opcja mode = "xt wyświetla tzw. diagram Hovmollera, gdzie na osi X są lokalizacje, a na osi Y czas, kolor odpowiada wartością wyświetlanej zmiennej. Diagram ten pozwala m.in na identyfikację braków danych oraz trendów w przestrzeni/czasie.
stplot(stfdf, mode = "xt", xlab = "Lokalizacja", ylab = "Czas")