Как можно наложить линию на гистограмму с помощью ggplot2?

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

Во-первых, мне нужно суммировать (суммировать) данные по группам, а во-вторых, я хотел бы преобразовать одну из серий (df2) в строку.

df <- data.frame(grp=c("A","A","B","B","C","C"),val=c(1,1,2,2,3,3))  
df2 <- data.frame(grp=c("A","A","B","B","C","C"),val=c(1,4,3,5,1,2))  
ggplot(df, aes(x=grp, y=val)) +   
    geom_bar(stat="identity", alpha=0.75) +  
    geom_bar(data=df2, aes(x=grp, y=val), stat="identity", position="dodge")

person user338714    schedule 02.12.2010    source источник


Ответы (2)


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

df <- data.frame(grp=c("A","A","B","B","C","C"),val=c(1,2,3,1,2,3))
df2 <- data.frame(grp=c("A","A","B","B","C","C"),val=c(1,4,3,5,0,2))

p <- ggplot(df, aes(x=grp, y=val)) 
p <- p + geom_bar(stat="identity", alpha=0.75) 

p + geom_line(data=df2, aes(x=grp, y=val), colour="blue")

В качестве альтернативы, если приведенный выше пример данных верен, вы можете нанести эту информацию в виде точки с помощью geom_point(data = df2, aes(x = grp, y = val), colour = "red", size = 6). Очевидно, вы можете изменить цвет и размер по своему вкусу.

РЕДАКТИРОВАТЬ: В ответ на комментарий

Я не совсем уверен, как должен выглядеть визуальный эффект многочлена частоты по гистограмме. Должны ли значения x быть связаны друг с другом? Во-вторых, вы продолжаете ссылаться на нужные строки, но ваш код показывает geom_bar(), что, я полагаю, не то, что вам нужно? Если вам нужны строки, используйте geom_lines(). Если два приведенных выше предположения верны, то вот способ сделать это:

 #First let's summarise df2 by group
 df3 <- ddply(df2, .(grp), summarise, total = sum(val))
>  df3
  grp total
1   A     5
2   B     8
3   C     3

#Second, let's plot df3 as a line while treating the grp variable as numeric

p <- ggplot(df, aes(x=grp, y=val))
p <- p + geom_bar(alpha=0.75, stat = "identity") 
p + geom_line(data=df3, aes(x=as.numeric(grp), y=total), colour = "red")
person Chase    schedule 02.12.2010
comment
На самом деле, я ищу способ построить гистограмму, содержащую две разные серии, скрыть одну из полос и вместо этого провести линию (если возможно, плавную) через верхнюю часть того места, где должны были быть полосы для скрытой серии ( подобно тому, как можно наложить полином частоты на гистограмму). - person user338714; 02.12.2010
comment
Я уточнил исходный вопрос. Спасибо за вашу помощь до сих пор - похоже, я пропустил шаг, чтобы сначала обобщить данные. - person user338714; 02.12.2010
comment
@user338714 user338714 - обновленный ответ, я все еще немного не понимаю, что вам здесь нужно на самом деле. Если то, что вы хотите, не указано выше, можете ли вы найти пример окончательного изображения, которое вы хотели бы иметь? - person Chase; 02.12.2010
comment
Это именно то, что я искал! Спасибо. - person user338714; 02.12.2010

Вы можете получить групповые итоги разными способами. Один из них является

with(df, tapply(val, grp, sum))

Для простоты вы можете объединить данные столбцов и линий в один набор данных.

df_all <- data.frame(grp = factor(levels(df$grp)))
df_all$bar_heights <- with(df, tapply(val, grp, sum))
df_all$line_y <- with(df2, tapply(val, grp, sum))

Гистограммы используют категориальную ось X. Чтобы наложить линию, вам нужно преобразовать ось в числовую.

ggplot(df_all) +
   geom_bar(aes(x = grp, weight = bar_heights)) +
   geom_line(aes(x = as.numeric(grp), y = line_y))

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

person Richie Cotton    schedule 02.12.2010
comment
Хороший ответ (+1)! Мне нравится этот подход. Я предполагаю, что это зависит от того, откуда берутся исходные исходные данные, для которых потребуется меньше кодирования. - person Chase; 02.12.2010