график скрипки ggplot2 с шириной от столбца

Я новичок в R и использую его только для визуализации, поэтому могу упустить что-то простое.

Я просто хочу, чтобы у меня было два столбца, которые должны быть осями x и y. Третий столбец у меня должен определять ширину графика. Я не продвинулся далеко с кодом, хотя пробовал много вещей из разных ответов. Допустим, я так далеко в коде:

ggplot(disM, aes(x=study, y=value)) +
  geom_violin() +
  labs(list(title="Distribution", x="Studies", y="Ranges"))

который на самом деле ничего не достигает.

У меня есть такая таблица:

  Col0         study     value
1    30-31 breast cancer    357263
2    32-33 breast cancer    352067
3    34-35 breast cancer    340264
4    36-37 breast cancer    309827
5    38-39 breast cancer    298684
6    40-41 breast cancer    322570
7    42-43 breast cancer    338480
8    44-45 breast cancer    354451
9    46-47 breast cancer    429183
10   48-49 breast cancer    396942
11   50-51 breast cancer    415195
12   52-53 breast cancer    368217
13   54-55 breast cancer    445884
14   56-57 breast cancer    395652
15   58-59 breast cancer    386643
16   60-61 breast cancer    461940
17   62-63 breast cancer    473772
18   64-65 breast cancer    464228
19   66-67 breast cancer    485851
20   68-69 breast cancer    513411
21   70-71 breast cancer    576618
22   72-73 breast cancer    588724
23   74-75 breast cancer    634343
24   76-77 breast cancer    584662
25   78-79 breast cancer    608901
26   80-81 breast cancer    617286
27   82-83 breast cancer    659318
28   84-85 breast cancer    757167
29   86-87 breast cancer   1044465
30   88-89 breast cancer    982901
31   90-91 breast cancer   1114269
32   92-93 breast cancer   1110257
33   94-95 breast cancer   1742966
34   96-97 breast cancer   6379974
35   98-99 breast cancer   3437746
36 100-101 breast cancer 118984063
37   30-31  renal cancer   1055566
38   32-33  renal cancer   1089405
39   34-35  renal cancer   1228087
40   36-37  renal cancer   1265606
41   38-39  renal cancer   1264919
42   40-41  renal cancer   1248949
43   42-43  renal cancer   1391738
44   44-45  renal cancer   1453100
45   46-47  renal cancer   1443915
46   48-49  renal cancer   1429785
47   50-51  renal cancer   1372041
48   52-53  renal cancer   1339706
49   54-55  renal cancer   1418135
50   56-57  renal cancer   1484162
51   58-59  renal cancer   1582617
52   60-61  renal cancer   1571977
53   62-63  renal cancer   1652503
54   64-65  renal cancer   1742230
55   66-67  renal cancer   1859936
56   68-69  renal cancer   1928028
57   70-71  renal cancer   2041783
58   72-73  renal cancer   2108994
59   74-75  renal cancer   2154244
60   76-77  renal cancer   2218430
61   78-79  renal cancer   2333206
62   80-81  renal cancer   2377262
63   82-83  renal cancer   2345651
64   84-85  renal cancer   2402114
65   86-87  renal cancer   2519284
66   88-89  renal cancer   2542761
67   90-91  renal cancer   2587606
68   92-93  renal cancer   2308279
69   94-95  renal cancer   2980927
70   96-97  renal cancer  14108950
71   98-99  renal cancer   2762116
72 100-101  renal cancer 211513230

Ось X должна быть столбцом исследования, y должна быть Col0, а ширина графика скрипки должна быть столбцом значений. Я не могу разделить col0, так как у меня есть данные только в виде диапазона.

Любой указатель на то, что проверить, как это сделать, будет оценен. Извините, если пропустил аналогичный вопрос.

заранее спасибо


person Erkin Acar    schedule 27.08.2016    source источник
comment
Я подозреваю, что вы не знаете, что изображает скрипичный сюжет.   -  person Roland    schedule 28.08.2016
comment
Как вы ожидаете, что ваша фигура будет выглядеть. Возможно, вы могли бы добавить эскиз, чтобы уточнить   -  person Richard Telford    schedule 28.08.2016


Ответы (2)


Я собираюсь предположить. (Если я прав, вы также можете поискать информацию о графиках пирамид.)

Измените порядок меток так, чтобы "100-101" действительно стояло в конце:

disM$Col0 <- factor(disM$Col0,levels=unique(disM$Col0))

Измените порядок, чтобы упростить рисование полигонов (хотелось бы, чтобы был более простой способ сделать это, но я не могу его придумать):

library(plyr)
disM2 <- ddply(disM,"study",
   function(dd) with(dd,
             data.frame(y=c(as.numeric(Col0),rev(as.numeric(Col0))),
                        x=c(-value/2,rev(value/2)))))


library(ggplot2); theme_set(theme_bw())
ggplot(disM2)+
    geom_polygon(aes(x,y),alpha=0.5)+
    facet_wrap(~study)+
    labs(list(title="Distribution"))+
    scale_y_continuous(breaks=as.numeric(disM$Col0),
                       labels=disM$Col0)+
    scale_x_continuous(labels=NULL)

введите здесь описание изображения

person Ben Bolker    schedule 27.08.2016
comment
Спасибо за информацию и код! Я просто хотел показать ширину графика со значениями, но для графика скрипки я считаю, что мне нужны строки, равные значению в столбце значений для каждого столбца 0. Это действительно полезно, и я считаю, что сюжет пирамиды будет лучше, хотя меня попросили сделать скрипку. - person Erkin Acar; 28.08.2016

Другой способ принять следующий.

Сначала вы должны рассчитать маркеры ваших классов (максимум класса + минимум класса / 2). В вашем случае это середина ваших интервалов (которые вы можете извлечь, используя levels(x = my_data$col0)).

my_data$class_mark <- rep(x = seq(from = 30.5, to = 100.5, by = 2), times = 2)

Затем вы должны разделить свои данные:

my_data_br <- my_data[which(my_data$study == "breast cancer"),]
my_data_re <- my_data[which(my_data$study == "renal cancer"),]

в вашем столбце value действительно огромные числа, поэтому вы должны разделить их на минимум:

my_data_br$value <- my_data_br$value/min(my_data_br$value)
my_data_re$value <- my_data_re$value/min(my_data_re$value)

После этого вы должны повторить каждый знак класса столько раз, сколько его value.

classmark_rep_br <- rep(x = my_data_br[,4], times = my_data_br[,3])
br_rep <- rep("breast cancer", times = length(x = classmark_rep_br))
br_data <- cbind.data.frame(br_rep, classmark_rep_br)
names(br_data) <- c("study", "value")

classmark_rep_re <- rep(x = my_data_re[,4], times = my_data_re[,3])
re_rep <- rep("renal cancer", times = length(x = classmark_rep_re))
re_data <- cbind.data.frame(re_rep, classmark_rep_re)
names(re_data) <- c("study", "value")

И, наконец, создайте новую базу данных:

my_data2 <- rbind.data.frame(br_data, re_data)

Теперь вы можете сделать свой график настолько красивым, насколько хотите (например, следующий) и сохранить его:

my_graph <- ggplot(data = my_data2, aes(x = study, y = value, fill = study)) + geom_violin() + 
  theme(legend.position = "none", panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        axis.text = element_text(size = 10, face = "bold"), panel.background = element_blank(), 
        axis.line = element_line(colour = "black")) + 
  labs(x = "", y = "") + scale_fill_brewer(palette="Pastel1") + 
  scale_x_discrete(labels = c("Breast cancer", "Renal cancer")) + 
  scale_y_continuous(breaks = c(30.5, 40.5, 50.5, 60.5, 70.5, 80.5, 90.5, 100.5),
                     labels = c("30-31", "40-41", "50-51", "60-61", "70-71", "80-81", "90-91", "100-101"))

    ggsave(plot = my_graph, filename = "my_graph", path = "output/path/", device = "png", dpi = 200)
person Manuel Sánchez Mendoza    schedule 08.08.2017