2013-05-07 26 views
7

znalazłem piękny przykład kreślenia wypukłe kształty kadłuba za pomocą ggplot z ddply tutaj: Drawing outlines around multiple geom_point groups with ggplotConvex ggplot kadłuba za pomocą data.tables w R

pomyślałem, że spróbować czegoś podobnego - stworzyć coś jak Ashby diagramie --to praktyka z pakietem data.table:

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

set.seed(1) 

Tu zdefiniować prostą tabelę:

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

I wtedy zdefiniować pozycje kadłuba poziomie:

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

Więc moja myśl była scalić kadłuby z dt, tak, że mogę w końcu manipulować kadłubów, aby w odpowiedniej formie do ggplot (pokazany poniżej dla porównania):

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

Ale wydaje się, że jakkolwiek próbuję połączyć kadłuby i dt, pojawia się błąd. Na przykład scalenie (kadłuby, dt) powoduje błąd, jak pokazano w przypisie 1.

Wygląda na to, że powinienem być prosty i jestem pewien, że po prostu brakuje mi czegoś oczywistego. Jakikolwiek kierunek do podobnego postu lub myśli na temat przygotowania kadłuba do ggplot jest bardzo doceniany. Lub jeśli uważasz, że najlepiej jest trzymać się podejścia ddply, proszę dać mi znać.

Przykład niepożądany Wydajność:

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

powoduje MES wielokątów przecinających: undesired output

Przypis 1: Błąd vecseq (f__, len__ jeśli (umożliwić .cartesian) NULL else as.integer (max (nrow (x),: Połączyć wyniki w 60 wierszach, więcej niż 15 = max (Nrow (x), Nrow (i)). Sprawdź, czy nie występują podwójne wartości klucza w i, z których dołącz do tego samego grupuj w x wielokrotnie. Jeśli wszystko jest w porządku, spróbuj wpisać j i upuszczając by (by-without-by), aby j przebiegła dla każdej grupy, aby uniknąć dużej alokacji. Jeśli jesteś pewien, że chcesz kontynuować, uruchom ponownie za pomocą allow.cartesian = TRUE. W przeciwnym razie wyszukaj ten komunikat o błędzie w FAQ, Wiki, Stack Overflow i datatable-help, aby uzyskać poradę.

+0

Zgaduję, że istnieje elegancki sposób robienia tego. Mając taką zdolność, myślę, że metoda ta mogłaby być łatwo rozszerzona, aby tworzyć fabułę w stylu Ashby. Na przykład: http://commons.wikimedia.org/wiki/File:Ashby_plot_big.jpg – Docuemada

+2

+1 za pokazanie swoich wysiłków i jasne wyjaśnienie, czego chcesz. Pamiętaj, że wywołanie 'library' w twojej własnej funkcji jest prawdopodobnie niepotrzebne (i nieefektywne, jeśli zamierzasz wielokrotnie wywoływać tę funkcję). –

Odpowiedz

8

Oto, co chcesz zrobić.Generowanie jakieś losowe dane:

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

Tutaj jest gdzie magia dzieje:

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

kreślenie Rezultat:

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

produkuje

enter image description here

I t działa, ponieważ chull zwraca wektor indeksów, które należy wybrać z danych w celu utworzenia wypukłego kadłuba. Następnie dzielimy każdą pojedynczą ramkę danych na .SD[...], a data.table łączy je razem przez level.

+0

allow.cartesian to sztuczka, o której nie wiedziałem, dziękuję. Tak jak w twoim przykładzie, problem, który mam, to utrzymywanie informacji o poziomie. Autor pytania: http://stackoverflow.com/questions/14419493/drawing-outlines-around-multiple-geom-point-groups-with-ggplot był w stanie stworzyć wypukłe kształty kadłuba wokół wielu grup za pomocą ddply. Zasadniczo staram się powtórzyć wynik oryginalnego pytania autora za pomocą podejścia data.table. – Docuemada

+0

Czy możesz wyjaśnić, co masz na myśli, mówiąc "zachowaj informacje o poziomie"? Tak jak w przypadku "kadłubów" i "dt" jak powyżej, jakie ma być wyjście? –

+0

kadłub [dt, allow.cartesian = TRUE] zwraca tabelę danych z 60 wierszy. Jednak w przypadku trzech kadłubów "a", "b" i "c" nie powinienem potrzebować 60 punktów, aby opisać kształty, ponieważ niektóre punkty znajdują się wewnątrz kształtu. Podam przykład niepożądanego wyniku w moim pytaniu, aby pomóc zilustrować. +1 za przyzwolenie. Kartezjusz przy okazji. – Docuemada