2014-06-18 9 views
6

Ich arbeite mit dem HURDAT-Dataset, um Hurrikan-Tracks zu plotten. Ich habe derzeit ein SpatialPointsDataFrame Objekt in R erzeugt, 2004.Convert SpatialPointsDataFrame in SpatialLinesDataFrame in R

> str(cluster.2004.sdf) 
Formal class 'SpatialPointsDataFrame' [package "sp"] with 5 slots 
    [email protected] data  :'data.frame': 2693 obs. of 4 variables: 
    .. ..$ Sid  : int [1:2693] 1331 1331 1331 1331 1331 1331 1331 1331 1331 1331 ... 
    .. ..$ clusterid: num [1:2693] 2 2 2 2 2 2 2 2 2 2 ... 
    .. ..$ name  : Factor w/ 269 levels "","ABBY  ",..: 6 6 6 6 6 6 6 6 6 6 ... 
    .. ..$ WmaxS : num [1:2693] 78.9 82.8 80.9 70.9 76.9 ... 
    [email protected] coords.nrs : num(0) 
    [email protected] coords  : num [1:2693, 1:2] 754377 612852 684956 991386 819565 ... 
    .. ..- attr(*, "dimnames")=List of 2 
    .. .. ..$ : NULL 
    .. .. ..$ : chr [1:2] "lon" "lat" 
    [email protected] bbox  : num [1:2, 1:2] -3195788 1362537 4495870 9082812 
    .. ..- attr(*, "dimnames")=List of 2 
    .. .. ..$ : chr [1:2] "lon" "lat" 
    .. .. ..$ : chr [1:2] "min" "max" 
    [email protected] proj4string:Formal class 'CRS' [package "sp"] with 1 slots 
    .. .. [email protected] projargs: chr "+proj=lcc +lat_1=60 +lat_2=30 +lon_0=-60 +ellps=WGS84" 

    > summary(cluster.2004.sdf) 
Object of class SpatialPointsDataFrame 
Coordinates: 
     min  max 
lon -3195788 4495870 
lat 1362537 9082812 
Is projected: TRUE 
proj4string : 
[+proj=lcc +lat_1=60 +lat_2=30 +lon_0=-60 +ellps=WGS84] 
Number of points: 2693 
Data attributes: 
     Sid   clusterid    name   WmaxS  
Min. :1331 Min. :1.000 IVAN  :517 Min. : 14.83 
1st Qu.:1334 1st Qu.:2.000 FRANCES :403 1st Qu.: 31.35 
Median :1337 Median :3.000 JEANNE :379 Median : 50.04 
Mean :1337 Mean :2.898 KARL  :283 Mean : 61.66 
3rd Qu.:1339 3rd Qu.:4.000 DANIELLE :271 3rd Qu.: 90.40 
Max. :1341 Max. :4.000 BONNIE :253 Max. :142.52 
           (Other) :587 

Jeder Sturm für das Jahr ungefähr so ​​aussieht hat eine eindeutige ID Referenz Sturm der Bezeichnung „Sid“. Ich möchte den SpatialPointsDataFrame mit dem "Sid" gruppieren und alle Punkte in eine Linie umwandeln.

Ich habe mit ddply aus dem plyr-Paket, aber ehrlich gesagt keine Ahnung, was ich tue. Ich weiß, dass ich dies tun kann, indem ich jede Zeile im Datenrahmen umschlinge und Koordinaten an eine Liste angehängt und diese Liste dann mit der Funktion Linien aus dem Paket sp umwandle.

Allerdings würde ich lieber eine mehr R Art der Konvertierung. Dank Richard

+0

All „R Wege“ letztlich mit einer Liste beschäftigen , aber Sie können split (x, id) als Start verwenden. Wichtiger ist, ob Sie einfache (wahrscheinlich) oder komplexe Linien wollen. Sie möchten eine Datenzeile mit Attributen für jede eindeutige ID? (einfach) – mdsumner

Antwort

6

Das Problem mit der Lösung des mdsumner besteht darin, dass die resultierende data.frame eine Zeile für jede Zeile haben muss, aber in seinem Code gibt es eine Zeile für jeden Punkt. Der korrigierte Code wäre:

## example data 
d <- data.frame(x=runif(7), y=runif(7), id = c(rep("a", 3), rep("b", 4))) 

library(sp)  
coordinates(d) <- ~x+y 

## list of Lines per id, each with one Line in a list 
x <- lapply(split(d, d$id), function(x) Lines(list(Line(coordinates(x))), x$id[1L])) 

# the corrected part goes here: 
lines <- SpatialLines(x) 
data <- data.frame(id = unique(d$id)) 
rownames(data) <- data$id 
l <- SpatialLinesDataFrame(lines, data) 

So ist das Problem im Grunde ist, dass Sie eine data.frame für die Linien zu schaffen haben, von id gruppiert (eine Zeile für jede Zeile). In dem Fall, wenn außer der id keine Daten vorhanden sind, ist es ziemlich einfach. Wenn Sie jedoch einige anderen Daten fro die ursprünglichen SpatialPointDataFrame zu Gruppe benötigen, müssen Sie einige Gruppierungsfunktionen wie tapply verwenden, aggregate oder meinen Favoriten verwenden - sqldf:

data <- sqldf(' 
select id, max(something), sum(something_else) 
from d 
group by id 
') 
+0

Danke.Ich musste dies als die Antwort markieren, aber update mdsumner auch –

+0

@Richard du bist willkommen – TMS

3
## example data 
d <- data.frame(x=runif(7), y=runif(7), id = c(rep("a", 3), rep("b", 4))) 
##split(d, d$id) 

library(sp)  
coordinates(d) <- ~x+y 

## list of Lines per id, each with one Line in a list 
x <- lapply(split(d, d$id), function(x) Lines(list(Line(coordinates(x))), x$id[1L])) 

## or one Lines in a list, with all Line objects 
## x <- list(Lines(lapply(split(d, d$id), function(x) Line(coordinates(x))), paste(unique(d$id), collapse = "_"))) 

## etc. 
SpatialLines(x, CRS(as.character(NA))) 

## need to be careful here, assuming one Lines per original row 
## and we trash the original rownames . . . 
SpatialLinesDataFrame(SpatialLines(x, CRS(as.character(NA))), d[,"id", drop = FALSE], match.ID = FALSE) 
+0

@mdsummer. Danke für die Antwort. Ich kann meinen Code nicht funktionieren lassen. Wenn ich exakt Zeile für Zeile kopiere und in RI laufe, bekomme ich den Fehler:> SpatialLinesDataFrame (SpatialLines (x, CRS (as.zeichen (NA))), d [, "id", drop = FALSE], match.ID = FALSE) Fehler in SpatialLinesDataFrame (SpatialLines (x, CRS (as.character (NA))),: Länge von data.frame stimmt nicht mit der Anzahl der Linien Elemente überein –