2014-06-18 58 views
6

我正在使用HURDAT數據集繪製颶風軌跡。 我目前已經產生了R A SpatialPointsDataFrame對象,它看起來像這樣爲2004年。將SpatialPointsDataFrame轉換爲R中的SpatialLinesDataFrame

> 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 

每次風暴都有標記爲「錫德」的獨特風暴的id引用。 我想通過「Sid」對SpatialPointsDataFrame進行分組,並將所有點轉換爲一條線。

我已經有了從plyr包ddply去,但坦率地不知道我在做什麼。 我知道我可以通過循環數據框中的每一行並將座標附加到列表中,然後使用sp包中的Lines函數轉換該列表。

但是,我寧願更多的R轉換方式。 感謝 理查德

+0

所有的「R方式」最終對付列表,但是你可以使用split(x,id)作爲開始。更重要的是你是否想要簡單(可能)或複雜的線條。你想爲每個唯一的ID的屬性的數據行? (簡單) – mdsumner

回答

6

與mdsumner的解決方案的問題是,所得data.frame必須有一個行的每一行,但在他的代碼中有每個點一行。更正後的代碼將是:

## 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) 

所以basicly的問題是,你必須創建爲線,通過ID分組一data.frame(一個行每行)。在上述情況下,除了id之外沒有數據,這很容易。如果需要組來回回原來SpatialPointDataFrame一些其他數據雖然,你必須使用一些分組功能,如tapplyaggregate,或者用我的最愛 - sqldf

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

謝謝,我不得不將這個標記爲答案,但upvote mdsumner 。 –

+0

@理查德,不客氣 – 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。感謝你的回答。我似乎無法讓你的代碼工作。如果我完全複製線條並在RI中運行,會收到以下錯誤:> SpatialLinesDataFrame(SpatialLines(x,CRS(as.character(NA))),d [,「id」,drop = FALSE],match.ID = FALSE ) SpatialLinesDataFrame中的錯誤(SpatialLines(x,CRS(as.character(NA))),: data.frame的長度與行數的元素不匹配 –