style renderdatatable extension entries data color r merge ggplot2 data.table convex-hull

renderdatatable - render table shiny



Ggplot de casco convexo usando data.tables en R (1)

Encontré un buen ejemplo de trazado de formas convexas de casco usando ggplot con ddply aquí: Dibujando esquemas alrededor de múltiples grupos geom_point con ggplot

Pensé en probar algo similar, crear algo así como un Diagrama de Ashby, para practicar con el paquete de data.table:

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

Aquí defino una tabla simple:

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

Y luego defino las posiciones del casco por nivel:

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

Entonces mi idea era fusionar cascos con dt, para poder eventualmente manipular los cascos para obtener la forma adecuada para ggplot (se muestra a continuación para referencia):

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

Pero parece que de cualquier forma que trato de fusionar cascos y dt, me sale un error. Por ejemplo, merge (hulls, dt) produce el error como se muestra en la nota al pie 1 .

Parece que debería ser simple, y estoy seguro de que me estoy perdiendo algo obvio. Cualquier dirección a una publicación similar o ideas sobre cómo preparar el casco para ggplot es muy apreciada. O si crees que es mejor seguir con el enfoque ddply, házmelo saber.

Ejemplo de resultado no deseado:

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

da como resultado un lío de polígonos que se entrecruzan:

Nota al pie 1: Error en vecseq (f__, len__, if (allow.cartesian) NULL else as.integer (max (nrow (x),: Unir resultados en 60 filas; más de 15 = max (nrow (x), nrow ( i)). Compruebe si hay valores clave duplicados en i, cada uno de los cuales se une al mismo grupo en x una y otra vez. Si eso está bien, intente incluir j y pasar by (by-without-by) para que j se ejecute para cada grupo para evitar la gran asignación. Si está seguro de que desea continuar, vuelva a ejecutar con allow.cartesian = TRUE. De lo contrario, busque este mensaje de error en las preguntas frecuentes, Wiki, Stack Overflow y datatable-help para obtener asesoramiento.


Esto es lo que quieres hacer. Generando algunos datos aleatorios:

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

Aquí es donde sucede la magia:

hulls <- dt[, .SD[chull(xdata, ydata)], by = level]

Trazando el resultado:

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

produce

Funciona porque chull devuelve un vector de índices que deben seleccionarse a partir de los datos para formar un casco convexo. Luego subconjuntos de cada marco de datos individual con .SD[...] y data.table une por level .