2
votes

My data frame:

    N   P   E   S
W1 3.5 3.5 3.4 3.5
w2 3.4 3.7 3.6 3.5
w3 3.5 3.4 3.5 3.5
w4 3.5 3.4 3.5 3.5
w5 3.5 3.4 3.5 3.5
w6 3.5 3.4 3.5 3.5
w7 3.5 3.4 3.5 3.5
w8 3.5 3.4 3.5 3.5

and code for barplot

mat <- as.matrix(t(tabela.matrix))

qw <- barplot(mat, beside = TRUE, axisnames = FALSE, ylim = c(0, 6),
              col = c("yellow", "deepskyblue1", "yellowgreen", "orchid4"))

text(colMeans(qw[2:3, ]), -0.25, labels = colnames(mat), xpd = TRUE, srt = 15)
text(qw, 0, round(as.matrix(t(tabela.matrix)), 1), cex = 1, pos = 3, srt = 90)

legend(3.2, -0.6, c("N","P","E", "S"),
       fill = c("yellow", "deepskyblue1", "yellowgreen", "orchid4"),
       horiz = TRUE, xpd = TRUE)

produces this barplot enter image description here

So on my barplot I need to add line that indicates subtraction: max-min values per row. So am using below code to get the subtraction.

max.tmp <- apply(df, 1, max)
min.tmp <- apply(df, 1, min)
substr.tmp <- max.tmp - min.tmp

Now I would like to add red line indicating values in substr.tmp. The code lines() doesn't work.

My output (red line) should "look" like this (it is picture form excel and i am interested in adding line, not the data in the picture itself)

enter image description here


A dput of the data:

structure(c(3.46666666666667, 3.35, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.45555555555556, 3.7, 3.36666666666667, 3.36666666666667, 3.36666666666667, 3.36666666666667, 3.36666666666667, 3.36666666666667, 3.40769230769231, 3.57692307692308, 3.53846153846154, 3.53846153846154, 3.53846153846154, 3.53846153846154, 3.53846153846154, 3.53846153846154, 3.51122994652406, 3.5156862745098, 3.49090909090909, 3.49090909090909, 3.49090909090909, 3.49090909090909, 3.49090909090909, 3.49090909090909 ), .Dim = c(8L, 4L), .Dimnames = list(c("a", "b", "c", "d", "e", "f", "g", "h"), NULL))
2
can you add dput of the data frame - rbm
@rbm, here it is structure(c(3.46666666666667, 3.35, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.45555555555556, 3.7, 3.36666666666667, 3.36666666666667, 3.36666666666667, 3.36666666666667, 3.36666666666667, 3.36666666666667, 3.40769230769231, 3.57692307692308, 3.53846153846154, 3.53846153846154, 3.53846153846154, 3.53846153846154, 3.53846153846154, 3.53846153846154, 3.51122994652406, 3.5156862745098, 3.49090909090909, 3.49090909090909, 3.49090909090909, 3.49090909090909, 3.49090909090909, 3.49090909090909 ), .Dim = c(8L, 4L), .Dimnames = list(c("a", "b", "c", "d", "e", "f", "g", "h"), NULL))' - Miha
your graphs are different - first goes 0 to 3.5 on y axis, the second goes to almost 6. Also in the max.tmp <- apply(df, 1, max) it's not clear what the df is.. Can you post the entire runable example with dput init. - rbm
The second picture is from excel, that someone else generated. I generated the first picture and I need just plot line like it is in second picture. - Miha

2 Answers

4
votes

With the data.table and ggplot2 packages you could do it as follows:

library(data.table)
df2 <- melt(setDT(df), id="name")
df2[, difference := max(value) - min(value), by = name]

library(ggplot2)
ggplot(df2, aes(x=name, y=value, fill=variable)) +
  geom_bar(stat="identity", position="dodge") +
  geom_line(aes(x=name, y=difference, group=1), size=1.5, color="red") +
  scale_x_discrete(expand = c(0,0)) +
  scale_y_continuous(expand = c(0,0), limits = c(0,4)) +
  scale_fill_manual(breaks = c("V1", "V2", "V3", "V4"),
                    values = c("yellow", "deepskyblue1", "yellowgreen", "orchid4")) +
  theme_bw()

this gives:

enter image description here

Used data:

m <- structure(c(3.46666666666667, 3.35, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.45555555555556, 3.7, 3.36666666666667, 3.36666666666667, 3.36666666666667, 3.36666666666667, 3.36666666666667, 3.36666666666667, 3.40769230769231, 3.57692307692308, 3.53846153846154, 3.53846153846154, 3.53846153846154, 3.53846153846154, 3.53846153846154, 3.53846153846154, 3.51122994652406, 3.5156862745098, 3.49090909090909, 3.49090909090909, 3.49090909090909, 3.49090909090909, 3.49090909090909, 3.49090909090909 ), .Dim = c(8L, 4L), .Dimnames = list(c("a", "b", "c", "d", "e", "f", "g", "h"), NULL))
df <- as.data.frame(m)
df$name <- rownames(df)
2
votes

This could work for you, but the differences in your example dataset (along with the one in your comments) will yield a funny looking plot:

#original code
mat <- as.matrix(t(tabela.matrix)) ;qw <- barplot(mat, beside=TRUE, axisnames = FALSE,ylim = c(0, 6), col=c("yellow", "deepskyblue1", "yellowgreen","orchid4")) ; text(colMeans(qw[2:3,]), -0.25, labels = colnames(mat), xpd=TRUE, srt=15); legend(3.2,-0.6, c("Nadrejeni","Podrejeni","Enak nivo", "Samoocenjevalec"), fill=c("yellow", "deepskyblue1", "yellowgreen","orchid4"), horiz=TRUE, xpd=TRUE)
text(qw, 0, round(as.matrix(t(tabela.matrix)), 1),cex=1,pos=3,srt=90)
legend(3.2, -0.6, c("N","P","E", "S"),
   fill = c("yellow", "deepskyblue1", "yellowgreen", "orchid4"),
   horiz = TRUE, xpd = TRUE)
#new code
par(new=TRUE)
plot(substr.tmp, lwd=2, col="red", type="l", axes=FALSE, ylim=c(0,6))
axis(4, ylim=c(0,6), col="red",col.axis="red",las=1)

Note that this plot has two axes, one black, one red. The red one is for the second plot. If you'd like to remove that, comment the last line. And, according to your expected output, this was kept in the original scale (hence ylim=c(0,6))