Aggregazione di punti sulla griglia usando R


14

Ho una domanda in merito all'aggregazione spaziale in R. Quello che sto cercando di fare è aggregare un set di dati di punti in una griglia. Non sono sicuro, tuttavia, come farlo poiché ho poca esperienza con questo tipo di cose. Speravo che qualcuno di voi potesse avere una guida utile / una possibile soluzione.

Il mio punto di vista è un set di dati contenente dati georeferenziati su eventi di conflitto in Africa (vedi www.acleddata.com). I punti sono georeferenziati con coordinate di latitudine / longitudine e contengono dati sul tipo e l'ora dell'evento. Quello che voglio fare è aggregare questi punti in una griglia di 1x1 gradi.

Pertanto una cella di griglia dovrebbe contenere le informazioni dei punti dati se si verifica un evento all'interno di quella cella di griglia. Il prodotto finale di questo dovrebbe essere un frame di dati o qualcosa che posso esportare in un file CSV poiché i dati sono destinati ad essere utilizzati in un set di dati del panel per l'analisi statistica.

Finora ho caricato e tracciato i dati e lo shapefile usando il codice qui sotto. Credo che dovrei usare la funzione over dal pacchetto sp per aggregare ma non so come. Spero che uno di voi possa aiutare.

Il codice che ho usato finora può essere trovato qui con il corrispondente risultato visivo laggiù .

Anche i suggerimenti per farlo in QGIS sono i benvenuti.


Questa è un'operazione semplice e veloce che richiede nient'altro che un po 'di aritmetica. Ma in quale formato vuoi l'output? "CSV" suggerisce solo che dovrebbe essere una tabella relazionale, ma ciò presenta un problema: quando si aggregano, ogni cella corrisponderà potenzialmente a un numero variabile di punti. Di solito si seleziona una delle due opzioni: o si emette un record per punto (incluso l'ID della sua cella contenente) o si emette un record per cella e si includono alcuni riepiloghi statistici dei punti che contiene. Di cosa hai bisogno?
whuber

1
Mi dispiace non l'ho specificato. Quello di cui ho bisogno è un record per cella . Uso il file csv per creare i dati del pannello in formato cell-year .
cavallo dell'anno

Risposte:


12

I dati scaricati contengono alcuni errori di localizzazione franchi, quindi la prima cosa da fare è limitare le coordinate a valori ragionevoli:

data.df <- read.csv("f:/temp/All_Africa_1997-2011.csv", header=TRUE, sep=",",row.names=NULL)
data.df <- subset(data.df, subset=(LONGITUDE >= -180 & LATITUDE >= -90))

Il calcolo delle coordinate e degli identificatori delle celle della griglia consiste semplicemente nel troncare i decimali dai valori di latitudine e longitudine. (Più in generale, per i raster arbitrari, prima centra e ridimensionali in unità di dimensioni delle celle, tronca i decimali, quindi ridimensiona e torna alla loro posizione originale, come mostrato nel codice per jisotto.) Possiamo combinare queste coordinate in identificatori univoci, collegandoli al frame di dati di input e scrivendo il frame di dati aumentato come file CSV. Ci sarà un record per punto:

ji <- function(xy, origin=c(0,0), cellsize=c(1,1)) {
  t(apply(xy, 1, function(z) cellsize/2+origin+cellsize*(floor((z - origin)/cellsize))))
}
JI <- ji(cbind(data.df$LONGITUDE, data.df$LATITUDE))
data.df$X <- JI[, 1]
data.df$Y <- JI[, 2]
data.df$Cell <- paste(data.df$X, data.df$Y)

Potresti invece voler un output che riassuma gli eventi all'interno di ogni cella della griglia. Per illustrare questo, calcoliamo i conteggi per cella e produciamo questi, un record per cella:

counts <- by(data.df, data.df$Cell, function(d) c(d$X[1], d$Y[1], nrow(d)))
counts.m <- matrix(unlist(counts), nrow=3)
rownames(counts.m) <- c("X", "Y", "Count")
write.csv(as.data.frame(t(counts.m)), "f:/temp/grid.csv")

Per altri riepiloghi, modificare l' functionargomento nel calcolo di counts. (In alternativa, utilizzare un foglio di calcolo o un software di database per riepilogare il primo file di output in base all'identificatore di cella.)

Come controllo, mappiamo i conteggi utilizzando i centri della griglia per individuare i simboli della mappa. (I punti situati nel Mar Mediterraneo, in Europa e nell'Oceano Atlantico hanno posizioni sospette: sospetto che molti di essi derivino dalla confusione di latitudine e longitudine nel processo di immissione dei dati.)

count.max <- max(counts.m["Count",])
colors = sapply(counts.m["Count",], function(n) hsv(sqrt(n/count.max), .7, .7, .5))
plot(counts.m["X",] + 1/2, counts.m["Y",] + 1/2, cex=sqrt(counts.m["Count",]/100),
     pch = 19, col=colors,
     xlab="Longitude of cell center", ylab="Latitude of cell center",
     main="Event counts within one-degree grid cells")

Mappa dell'Africa

Questo flusso di lavoro è ora

  • Completamente documentato (tramite il Rcodice stesso),

  • Riproducibile (rieseguendo questo codice),

  • Estensibile (modificando il codice in modi ovvi), e

  • Abbastanza veloce (l'intera operazione richiede meno di 10 secondi per elaborare queste 53052 osservazioni).


Il codice è perfettamente riproducibile. Ho un'altra domanda però. Invece di un riepilogo, come posso allegare le informazioni dal file di dati di input alla cella nella griglia creata?
cavallo dell'anno

1
Ciò non è possibile con una tabella di output , poiché le informazioni complete per le celle hanno una lunghezza variabile. Il modo corretto di registrare è con la prima forma di output che ho esposto: un record per punto con un attributo identificatore di cella. Uno di questi due formati - le tabelle per punto e per cella - sarà previsto da qualsiasi programma statistico che si sta utilizzando.
whuber

1
Ah ok. Capisco cosa intendi. Devi solo creare una griglia per tutte le celle e unirla. Grazie per l'aiuto.
cavallo dell'anno

3

Bene, quello che vuoi è un cosiddetto "Join spaziale" di base, che abbina due shapefile tra loro e alloca la somma (numero di conteggio) alla tabella degli attributi risultante. Se cerchi "Join spaziale in R" troverai numerosi esempi anche qui su GIS.Stackexchange. Ho rapidamente cercato su Google e ho trovato ad esempio questo codice pubblicato su una mailing list.

Se si desidera ottenere un join di attributo spaziale in QGIS, procedere come segue:

  • Salva le tue forme come file .shp (comando writeOGR dal pacchetto rgdal)
  • Caricali in QGIS. Ricrea la tua griglia vettoriale tramite il plug-in MMQGIS (Crea -> Crea livello griglia) con il ridimensionamento appropriato.
  • Utilizzare lo strumento "Unisci attributi" dal menu Vector -> Gestione dati. Seleziona un attributo del tuo livello punto (potrebbe trattarsi di una semplice colonna che rappresenta i valori VERO (1) o FALSO (0) per diversi eventi di conflitto).
  • Seleziona la griglia e somma tutte le occorrenze ed esegui. Successivamente vorrei anche tagliare la griglia con una forma del continente africano.

Se il Join in qualche modo fallisce (non funziona sempre per me), quindi attenersi a SEXTANTE e cercare la toolbox SAGA, che ha anche ottime funzioni di join.


Sebbene questa sia una soluzione, è particolarmente complessa e inefficiente dato che il riepilogo dei punti di una griglia è solo una questione di alcune semplici operazioni aritmetiche, che Reccelle. Usare shapefile, rgdalQGIS e Sextante è un po 'come raccomandare a qualcuno di noleggiare un moderno impianto industriale automatizzato per inchiodare due assi :-).
whuber

Proverò questo approccio questo fine settimana. Nel prossimo futuro potrei voler combinare vari file di forme tra loro in modo che questo possa essere utile. Grazie per l'input e i suggerimenti.
cavallo dell'anno

@whuber: è vero, ma se vuoi distribuire e magari modellare il tuo output, allora uno shapefile è la scelta ovvia. Tuttavia, bell'esempio di R!
Chiurlo

Alla fine l'ho provato. Ma il problema con questo approccio è che somma tutte le osservazioni sul poligono. Mentre idealmente voglio conservare le informazioni su diversi eventi nel tempo. Ma potrebbe essere che ho fatto qualcosa di sbagliato.
cavallo del
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.