我正在关注这个example创建多边形以使用 ggplot 进行绘制,如果我的数据是子集,我可以按照该示例创建单独的凸包;但是,当我尝试应用 ddply 时,因为我有一个分组变量,但我无法这样做。以下是示例中添加了分组变量的代码:
library(grDevices) # load grDevices package
df <- data.frame(X = c(-62, -40, 9, 13, 26, 27, 27),
Y = c( 7, -14, 10, 9, -8, -16, 12), id = c(1, 1, 1, 2, 2, 3, 3))
con.hull.pos <- ddply(df, .(id), summarize, hullpos = chull(X, Y)) # get convex hull positions by each ID
现在,要为每个 ID 获取完整的多边形,我们需要按照 con.hull.pos
中给出的每个 ID 获取所有行,但我们还需要添加每个 ID 的第一行组。
df[ddply(con.hull.pos, .(id), function(x) x[1, ])$hullpos, ] # first row of position
df[con.hull.pos$hullpos ,] ## all rows of position
rbind(df[con.hull.pos$hullpos ,] , df[ddply(con.hull.pos, .(id), function(x) x[1, ])$hullpos, ])
这里我的代码失败了,因为使用 ddply 的第一行与 ID 的凸包的第一行不同。因此,多边形并不完整。谁能帮我应用给定的example通过按变量分组。
手动子集化时,此代码会创建三个覆盖三个 id 区域的独立多边形
id1_df <- subset(df, id==1)
id1_con.hull.pos <- chull(id1_df$X, id1_df$Y)
id2_df <- subset(df, id==2)
id2_con.hull.pos <- chull(id2_df$X, id2_df$Y)
id3_df <- subset(df, id==3)
id3_con.hull.pos <- chull(id3_df$X, id3_df$Y)
id1_con.hull <- rbind(id1_df[id1_con.hull.pos,], id1_df [id1_con.hull.pos[1],])
id2_con.hull <- rbind(id2_df [id2_con.hull.pos ,], id2_df [id2_con.hull.pos [1],])
id3_con.hull <- rbind(id3_df [id3_con.hull.pos,], id3_df [id3_con.hull.pos[1],])
poly_borders <- rbind(id1_con.hull, id2_con.hull, id3_con.hull)
plot(Y ~ X, data = df) # plot data
lines(poly_borders) # add lines for convex hull
最佳答案
两个提示:
- 使用基 R 中的
chull
函数计算凸包。 - 使用
dlply
将生成的chull
存储在列表中,而不是数据帧
然后你的代码变成:
x <- dlply(df, .(id), function(piece)piece[chull(piece$X, piece$Y), -3])
plot(Y~X, df)
lapply(x, polygon)
这会产生这个图:
<小时/>
如果你想在ggplot
中绘制它,那就更容易了,但是使用ddply
:
x <- ddply(df, .(id), function(piece)piece[chull(piece$X, piece$Y), ])
ggplot(x, aes(X, Y, group=id)) + geom_polygon(fill="cyan", colour="blue") + geom_line()
关于r - 如何使用 ddply 获得凸包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11549495/