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
.