Столбчатый график с точками, но с разной эстетической длиной — ggplot2

#r #ggplot2 #bar-chart #aesthetics

#r #ggplot2 #столбчатая диаграмма #эстетика

Вопрос:

 I have a dataframe which I used the melt function to get to this (length = 118): 

 record_id          value Values
1           8     int_to_out     20
2          14     int_to_out     32
3           5     int_to_out     22
4           6     int_to_out     19
5          31     int_to_out     15
6          48     int_to_out     20
7         100     int_to_out     30
...       ...        ...        ...
113        87 symptom_to_int      7
114        72 symptom_to_int      4
115        99 symptom_to_int      3
116       102 symptom_to_int     36
117       103 symptom_to_int     13
118       111 symptom_to_int      6
  

Я создал столбчатый график с этим:

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

График содержит 59 y элементов, и мне нужно добавить к ним точки на основе исходных (не расплавленных) данных. Итак, я написал это:

 ggplot(t, aes(y=as.factor(record_id), x=Values, fill=value))   
    geom_bar(position=position_stack(reverse= TRUE), stat="identity")  
    geom_point(data = new_df, aes(x=sorolog, y = record_id), 
                colour = "#a81802", size = 4, shape = 1)
  

x = sorolog Имеет 59 значений для 59 идентификаторов, найденных в record_id .

Но когда я запускаю его, я получаю это:

     Error: Aesthetics must be either length 1 or the same as the data (59): fill
Run `rlang::last_error()` to see where the error occurred.
  

Я считаю, что это конфликт с расплавленными данными, поскольку его длина равна удвоению исходного фрейма данных.

Вопрос в том, как я могу добавить точки с такой разницей в длине aestetics?

Еще одна проблема: как я могу добавить вторую легенду к графику?

Я использовал этот код:

 ggplot()   
    geom_bar(data=t, aes(y=as.factor(record_id), x=Values, fill=value), 
        position=position_stack(reverse= FALSE), stat="identity", width = 0.5)  
        scale_fill_manual(values = c("brown1","chocolate1"),name = "", 
            labels = c("Hospitalization to Discharge", "Symptom to Hospitalization"))  
    geom_point(data = new_df, aes(x=sorolog, y = as.factor(record_id)), 
                colour = "darkcyan", size = 5, shape = 1) 
    geom_point(data = new_df, aes(x=final, y = as.factor(record_id)), 
                colour = "darkred", size = 4, shape = 16) 

        theme_minimal() 
    labs(title="Patient timeline - from symptoms to hospitalization and discharge",
        x ="Days", y = "Patient ID") 
    theme(text = element_text(family = "Garamond", color = "grey20"))
  

и получил это:
введите описание изображения здесь

но я не могу добавить легенду для элементов geom_point, как я могу это сделать?

Редактировать

С помощью редактирования от Дэйва Армстронга я получил это:

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

Комментарии:

1. На графике, который вы установили y=as.factor(record_id) , в то время как ваш new_df был y сопоставлен только с record_id . Если вы не настроили new_df$record_id учет заранее, то, скорее всего, ggplot2 пытается использовать это как непрерывную эстетику, а не дискретную ( as.factor ). Это то, что здесь происходит?

2. Есть ли что-то еще с именем sorolog или record_id, что он мог бы пытаться отобразить? Кажется бессмысленным, что в ошибке указано, что длина должна быть 59, а вы говорите, что существует 59 значений. Возможно, если это одна переменная является фактором, она может иметь остаточные уровни.

3. @chemdork123, просто пытался это сделать, но проблема остается той же.

4. … поскольку ошибка связана с fill aes (см. Сообщение об ошибке) Я бы попробовал создать fill=value локальный aes для geom_bar .

5. Да, я только что обнаружил, что это в сообщении об ошибке, и собирался опубликовать что-то, пока не увидел, что на это был дан ответ.

Ответ №1:

Без доступа к данным, которые вам нужно будет подтвердить, но если вы удалите данные и эстетику из ggplot() и поместите их в geom_bar() , это должно сработать:

 ggplot()   
    geom_bar(data=t, aes(y=as.factor(record_id), x=Values, fill=value), 
        position=position_stack(reverse= TRUE), stat="identity")  
    geom_point(data = new_df, aes(x=sorolog, y = record_id), 
                colour = "#a81802", size = 4, shape = 1)
  

Редактировать

Я добавляю ответ на вопрос о добавлении цветовой легенды для точек. Также добавлен размер и форма точек.

 ggplot()   
  geom_bar(data=t, aes(y=as.factor(record_id), x=Values, fill=value), 
           position=position_stack(reverse= FALSE), stat="identity", width = 0.5)  
  scale_fill_manual(values = c("brown1","chocolate1"),name = "", 
                    labels = c("Hospitalization to Discharge", "Symptom to Hospitalization"))  
  geom_point(data = new_df, aes(x=sorolog, y = as.factor(record_id), colour="Point Label 1",
                                size="Point Label 1", shape="Point Label 1"))    
  geom_point(data = new_df, aes(x=final, y = as.factor(record_id), colour="Point Label 2", 
                                size="Point Label 2", shape="Point Label 2"))   
  scale_colour_manual("points", values=c("Point Label 1" = "darkcyan", "Point Label 2" = "darkred"), 
                      labels= c("Point Label 1", "Point Label 2"))   
  scale_shape_manual("points", values=c("Point Label 1" = 1, "Point Label 2" = 16), 
                      labels= c("Point Label 1", "Point Label 2"))   
  scale_size_manual("points", values=c("Point Label 1" = 5, "Point Label 2" = 4), 
                     labels= c("Point Label 1", "Point Label 2"))   
  theme_minimal() 
  labs(title="Patient timeline - from symptoms to hospitalization and discharge",
       x ="Days", y = "Patient ID") 
  theme(text = element_text(family = "Garamond", color = "grey20"))
  

Хитрость здесь в том, чтобы поместить все атрибуты точки — цвет, размер и форму — в эстетику с одинаковыми метками. Сами атрибуты, предоставленные values , должны быть именованными векторами, имена которых совпадают с эстетическими именами. Я нашел этот пост полезным для объединения частей.

Основная идея заключается в том, что вам нужно добавить цветовую эстетику к точкам, но это не обязательно должно исходить из переменной во фрейме данных, вы можете создать это на лету.

Комментарии:

1. Это сработало, мне просто нужно было ввести y=as.factor(record_id) в geom_point(). Спасибо

2. у вас есть какие-нибудь идеи о том, как добавить две разные легенды, одну для geom_bar, а другую для geom_point?

3. @LucasLazari Я добавил ответ к ответу на первоначальный вопрос

4. @LucasLazari что вы подразумеваете под разделением? Вы имеете в виду, что хотите, чтобы они были рядом друг с другом, а не друг над другом? Если это так, то вы можете использовать position = position_nudge(y=.2) для одного набора точек и position = position_nudge(y=-.2) для другого набора точек

5. @LucasLazari Я отредактировал ответ, чтобы включить эстетику размера и формы. Это должно привести вас туда, куда вам нужно.