使用R中的data.tables的凸壳ggplot

Doc*_*ada 9 merge r convex-hull ggplot2 data.table

我在这里找到了一个使用ggplot和ddply绘制凸包形状的好例子:使用ggplot 绘制多个geom_point组周围的轮廓线

我以为我会尝试类似的东西 - 创建类似Ashby Diagram的东西 - 用data.table包练习:

test<-function()
{
library(data.table)
library(ggplot2)

set.seed(1)
Run Code Online (Sandbox Code Playgroud)

在这里我定义一个简单的表:

dt<-data.table(xdata=runif(15),ydata=runif(15),level=rep(c("a","b","c"),each=5),key="level")
Run Code Online (Sandbox Code Playgroud)

然后我按级别定义船体位置:

hulls<-dt[,as.integer(chull(.SD)),by=level]
setnames(hulls,"V1","hcol")
Run Code Online (Sandbox Code Playgroud)

所以我的想法是将船体与dt合并,这样我最终可以操纵船体以获得ggplot的正确形式(如下所示):

ashby<-ggplot(dt,aes(x=xdata,y=ydata,color=level))+
        geom_point()+
        geom_line()+
        geom_polygon(data=hulls,aes(fill=level))
}
Run Code Online (Sandbox Code Playgroud)

但似乎我尝试合并外壳和dt的任何方式,我得到一个错误.例如,merge(hulls,dt)产生错误,如脚注1所示.

这似乎应该很简单,我确信我只是遗漏了一些明显的东西.任何关于类似帖子的方向或关于如何为ggplot准备船体的想法都非常感谢.或者如果您认为最好坚持采用ddply方法,请告诉我.

不需要的输出示例:

test<-function(){
    library(data.table)
    library(ggplot2)
    dt<-data.table(xdata=runif(15),ydata=runif(15),level=rep(c("a","b","c"),each=5),key="level")
    set.seed(1)
    hulls<-dt[,as.integer(chull(.SD)),by=level]
    setnames(hulls,"V1","hcol")
    setkey(dt, 'level') #setting the key seems unneeded
    setkey(hulls, 'level')
    hulls<-hulls[dt, allow.cartesian = TRUE]
    ggplot(dt,aes(x=xdata,y=ydata,color=level))+
            geom_point()+
            geom_polygon(data=hulls,aes(fill=level))
}
Run Code Online (Sandbox Code Playgroud)

导致一堆乱七八糟的多边形: 不希望的输出

脚注1:

vecseq中的错误(f __,len __,if(allow.cartesian)其他为as.integer(max(nrow(x),: Join结果为60行;超过15 = max(nrow(x),nrow(i))检查i中的重复键值,每个键值一遍又一遍地连接到x中的同一组.如果没关系,尝试包含j并删除by(by-without-by),以便为每个组运行j以避免大如果您确定要继续,请使用allow.cartesian = TRUE重新运行.否则,请在FAQ,Wiki,Stack Overflow和datatable-help中搜索此错误消息以获取建议.

Vic*_* K. 9

这是你想要做的.生成一些随机数据:

library(ggplot2)
library(data.table)
# You have to set the seed _before_ you generate random data, not after
set.seed(1) 
dt <- data.table(xdata=runif(15), ydata=runif(15), level=rep(c("a","b","c"), each=5),
  key="level")
Run Code Online (Sandbox Code Playgroud)

这是神奇发生的地方:

hulls <- dt[, .SD[chull(xdata, ydata)], by = level]
Run Code Online (Sandbox Code Playgroud)

绘制结果:

ggplot(dt,aes(x=xdata,y=ydata,color=level)) +
    geom_point() +
    geom_polygon(data = hulls,aes(fill=level,alpha = 0.5))
Run Code Online (Sandbox Code Playgroud)

产生

在此输入图像描述

它的工作原理是因为chull返回需要从数据中选择的索引向量以形成凸包.然后,我们使用每个单独的数据框进行子集化.SD[...],并将data.table它们连接在一起level.

  • `hulls < - dt [dt [,.I [chull(xdata,ydata)],by = level] $ V1]`将更有效,因为`data.table`不会构造`.SD` (3认同)