我正在使用HURDAT数据集绘制飓风轨迹。 我目前在R中生成了一个SpatialPointsDataFrame对象,它在2004年看起来像这样。
> str(cluster.2004.sdf)
Formal class 'SpatialPointsDataFrame' [package "sp"] with 5 slots
..@ 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 ...
..@ coords.nrs : num(0)
..@ coords : num [1:2693, 1:2] 754377 612852 684956 991386 819565 ...
.. ..- attr(*, "dimnames")=List of 2
.. .. ..$ : NULL
.. .. ..$ : chr [1:2] "lon" "lat"
..@ 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"
..@ proj4string:Formal class 'CRS' [package "sp"] with 1 slots
.. .. ..@ 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"。 我想通过" Sid"对SpatialPointsDataFrame进行分组。并将所有点转换为一条线。
我从plyr包中找到了ddply,但坦率地说我不知道我在做什么。 我知道我可以通过循环数据框中的每一行并将坐标附加到列表,然后使用sp包中的Lines函数转换该列表来实现此目的。
但是,我更倾向于转换R方式。 谢谢 理查德
答案 0 :(得分:7)
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)
所以问题基本上就是你必须为行创建一个data.frame
,按id分组(每行一行)。如果上面没有id
之外的数据,那么这很简单。如果您需要对原始SpatialPointDataFrame
的其他一些数据进行分组,则必须使用某些分组功能,例如tapply
,aggregate
或使用我最喜欢的sqldf
:< / p>
data <- sqldf('
select id, max(something), sum(something_else)
from d
group by id
')
答案 1 :(得分:4)
## 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)
答案 2 :(得分:1)
从空间点数据帧到空间多边形数据帧
library(sp)
library(raster)
### Example data: creating a SpatialPointsDataFrame object
x = c(1,2,5,4,3)
y = c(3,2,3,6,6)
df_points <- as.data.frame(cbind(x,y))
S <- SpatialPoints(cbind(x,y))
# S <- SpatialPoints(list(x,y))
# S <- SpatialPoints(data.frame(x,y))
S
plot(S)
spdf <- SpatialPointsDataFrame(S, df_points)
spdf
plot(spdf)
# crs(spdf) <- ("+proj=utm +zone=23 +south +datum=WGS84 +units=m +no_defs") ### add a crs
### Convert the SpatialPointsDataFrame to SpatialPolygons
(Sr1 = Polygon(spdf[,1:2]))
(Srs1 = Polygons(list(Sr1), "s1"))
(SpP = SpatialPolygons(list(Srs1), 1:1, proj4string= crs("+proj=utm +zone=23 +south +datum=WGS84 +units=m +no_defs")))
plot(SpP, col = 3:3, pbg="white", add=T)
SpP ### can not write as shapefile
### Convert the SpatialPolygons to SpatialPolygonsDataFrame
shape_pol <- SpatialPolygonsDataFrame(SpP, match.ID=F, data= data.frame(x=spdf[1:1,1], y=spdf[1:1,2]))
shape_pol ### can be write as shapefile
plot(shape_pol, col = 4, add=T)
### write shapefile
library(rgdal)
writeOGR(shape_pol, paste0(getwd(), "/Output_shapes"), "p_to_shape_pol", driver="ESRI Shapefile")