Calcul des décalages spatiaux par an en R

8

Pour le moment, j'ai du mal à calculer un décalage spatial dans R. Je sais comment calculer le décalage dans un format à l'échelle de l'espace, mais je ne peux pas le faire sous une forme longue, c'est-à-dire avoir des observations répétées pour l'unité d'analyse.

Vous trouverez ci-dessous quelques données fictives pour illustrer ce que j'essaie de faire. Commençons par générer des observations d'événements qui m'intéressent.

# Create observations
pts<-cbind(set.seed(2014),x=runif(30,1,5),y=runif(30,1,5),
       time=sample(1:5,30,replace=T))
require(sp)
pts<-SpatialPoints(pts)

xet ysont les coordonnées tandis que timereprésente la période de temps pendant laquelle l'événement a lieu. Les événements doivent être agrégés en polygones qui est l'unité d'analyse. Dans cet exemple, les polygones sont des cellules de grille et pour des raisons de simplicité, les limites sont fixées dans le temps.

# Observations take place in different areas; create polygons for areas
X<-c(rep(1,5),rep(2,5),rep(3,5),rep(4,5),rep(5,5)) 
Y<-c(rep(seq(1,5,1),5))
df<-data.frame(X,Y)
df$cell<-1:nrow(df) # Grid-cell identifier
require(raster)
coordinates(df)<-~X+Y 
rast<-raster(extent(df),ncol=5,nrow=5)
grid<-rasterize(df,rast,df$cell,FUN=max)
grid<-rasterToPolygons(grid) # Create polygons 

Nous pouvons tracer les données juste pour avoir un aperçu de la distribution: Distribution d'événements

Pour le format à l'échelle de l'espace, je calculerais le décalage spatial de la manière suivante:

pointsincell=over(SpatialPolygons(grid@polygons),SpatialPoints(pts),
              returnList=TRUE)
grid$totalcount<-unlist(lapply(pointsincell,length))
require(spdep)
neigh<-poly2nb(grid) # Create neighbour list
weights<-nb2listw(neigh,style="B",zero.policy=TRUE) # Create weights (binary)
grid$spatial.lag<-lag.listw(weights,
                            grid$totalcount,zero.policy=TRUE) # Add to raster

Cependant, comme vous pouvez le voir, le faire de cette façon ne prend pas en compte le fait que les événements se produisent à différents moments dans le temps. Il agrège simplement tout au niveau du polygone. Maintenant, je veux calculer ce décalage spatial en tenant compte de cette dimension temporelle afin d'agréger les données dans ce cas au niveau polygone-temps.

Je me demande si quelqu'un a une suggestion utile sur la façon dont cela pourrait être accompli? Quelle est la manière la plus pratique de calculer les décalages spatiaux au format long?

J'ai jeté un coup d'œil au spacetimepaquet mais je n'ai pas réussi à l'appliquer.

horseoftheyear
la source
Avez-vous essayé de boucler la fonction spdep :: autocov_dist?
Jeffrey Evans
Non, je ne l'ai pas fait. Je fais un peu de piratage en utilisant le produit Kronecker.
horseoftheyear

Réponses:

2

Je pense que le moyen le plus simple d'y parvenir est d'utiliser des boucles et de créer le lag.listw () pour votre variable de comptage pour chaque année.

Quelque chose comme ça?

spatlag <- data.frame(id=NULL, time=NULL, lag=NULL)
for (y in sort(unique(data$time))){
  print(y)

Ensuite, à l'intérieur de la boucle for, vous sous-définissez à la fois les points et les polygones et exécutez la superposition. Ensuite, vous résumez le nombre de points pour chaque point dans le temps et les liez à la trame de données spatlag, un point dans le temps.

pointsincell=over(SpatialPolygons(grid@polygons),SpatialPoints(pts),
              returnList=TRUE)
grid$totalcount<-unlist(lapply(pointsincell,length))
require(spdep)
neigh<-poly2nb(grid) # Create neighbour list
weights<-nb2listw(neigh,style="B",zero.policy=TRUE) # Create weights (binary)
grid$spatial.lag<-lag.listw(weights,grid$totalcount,zero.policy=TRUE) # Add to raster
rbind(spatlag, grid)
}

Le code ci-dessus est juste à titre d'exemple. Donc: 1. Créez un bloc de données vide pour stocker les décalages 2. Pour la boucle pour chaque point dans le temps 3. Créez un sous-ensemble pour les points où le temps est égal au temps pour la boucle 4. Superposez les points sur la grille / le polygone 5. Additionnez le nombre de points dans chaque superposition de polygones (pourrait utiliser dplyr pour agréger) 6. Liez le nombre total de points à la trame de données vide.

spesseh
la source
Pour être honnête, je ne sais pas exactement comment cela fonctionne.
horseoftheyear
1

Ce serait beaucoup plus facile d'utiliser la slagfonction du splmpaquet.

Dites à R que vous data.frameêtes un bloc de données de panneau, puis travaillez avec pseries.

Veuillez noter que cela ne fonctionnera qu'avec un panneau équilibré. Juste pour vous donner un exemple:

library(plm)
library(splm)
library(spdep)

data("EmplUK", package = "plm")

names(EmplUK)
table(EmplUK$year)
#there should be 140 observations /year, but this is not the case, so tomake it balanced

library(dplyr)
balanced_p<-filter(EmplUK, year>1977 & year<1983)
table (balanced_p$year)
#now it is balanced

firm<-unique(balanced_p$firm)
#I'm using the coordinates (randomly generated) of the firms, but it works also if you use the polygons as you did in your question
coords <- cbind(runif(length(firm),-180,+180), runif(length(firm),-90,+90))
pts_firms<-SpatialPoints(coords)

#now tell R that this is a panel, making sure that the firm id and years are the first two columns of the df
p_data<-pdata.frame(balanced_p)
firm_nb<-knn2nb(knearneigh(pts_firms))
firm_nbwghts<-nb2listw(firm_nb, style="W", zero.policy=T)

#now you can easily create your spatial lag 
#I'm assuming here that the dependent variable is wage! 
p_data$splag<-slag(p_data$wage,firm_nbwghts)

p_data$wageest de classe pseries, tandis firm_nbwghtsqu'unlistw

Nemesi
la source
Intéressant. Pourrait essayer cela à l'avenir.
horseoftheyear
0

Je pense donc que j'ai trouvé une méthode pour le faire. Les données de sortie prendront la forme d'une trame de données normale. C'est un peu maladroit mais ça marche.

# Start by creating a panel (CSTS) data frame
grid$cc<-1:nrow(grid)
tiempo<-1:5
polygon<-as.vector(unique(unlist(grid$cc,use.names=FALSE)))

# Loop to create panel data frame
timeCol<-rep(tiempo,length(polygon))
timeCol<-timeCol[order(timeCol)]

polCol <- character()
for(i in tiempo){ 
 row <- polygon
 polCol <- c(polCol, row)
}

df<-data.frame(time=timeCol,nrow=polCol)
df$nrow<-as.numeric(df$nrow)
df<-df[order(df$time,df$nrow),] # Order data frame 

# Assign each point to its corresponding polygon
pts<-SpatialPointsDataFrame(pts,data.frame(pts$time)) # This is a bit clumsy
pts$nrow=over(SpatialPoints(pts),SpatialPolygons(grid@polygons),
              returnlist=TRUE) 

# Aggregate the data per polygon
pts$level<-1
pts.a<-aggregate(level~nrow+time,pts,FUN=sum) # No NA's

# Merge the data
df2<-merge(df,pts.a,all.x=T)
df2[is.na(df2$level),]$level<-0 # Set NA's to 0

# Create contiguity matrix
k<-poly2nb(grid,queen=TRUE) # Create neighbour list
W<-nb2listw(k,style="B",zero.policy=TRUE) # Spatial weights; binary
con<-as.matrix(listw2mat(W)) # Contiguity matrix

# Calculate spatial lag using Kronecker product
N<-length(unique(df2$nrow))
T<-length(unique(df2$time))
ident<-diag(1,nrow=T)
df2$SpatLag<-(ident%x%con)%*%df2$level # Done
horseoftheyear
la source