2

I have a data frame like

  Model1    Model2      Model3    Model4
      4          4          5         5
      4          4         NA        NA
      3          2          5         5
      2          2          3         3
      3          3          3         3
      3          3          4         4

I want to plot a barplot like

enter image description here

The x- axis will have the Model1,Model2,Model3 and Model4 and the bars will be the proportion of the scores in each column,i.e., 6 bars for each Model (in the full data I have the scores from 0 to 5)

How can this be done without having to create a dataframe using rbind or creating a matrix? Any help will be appreciated.

4
  • Have you tried anything yet? Have a look at this post stackoverflow.com/questions/22189435/… and adapt it accordingly Commented Mar 5, 2014 at 18:04
  • @infominer I am not so proficient in R. if you could shed some light given my problem Commented Mar 5, 2014 at 18:10
  • Why do you not want to transform your data? It would then be straight forward to plot using ggplot. Commented Mar 5, 2014 at 18:23
  • @user20650 what transformation do you suggest? Commented Mar 5, 2014 at 18:40

1 Answer 1

2

You can't do it without changing the format of your data, but it isn't difficult to do so.

You can use the melt option of the reshape2 package.

I created a data frame of your data:

   df1<-data.frame("Model1"=c(4,4,3,2,3,3),
                   "Model2"=c(4,4,2,2,3,3),
                   "Model3"=c(5,NA,5,3,3,4),
                   "Model4"=c(5,NA,5,3,3,4))

  Model1 Model2 Model3 Model4
1      4      4      5      5
2      4      4     NA     NA
3      3      2      5      5
4      2      2      3      3
5      3      3      3      3
6      3      3      4      4

Next you can reshape the data using the reshape2 package:

library(reshape2)
df2<-melt(df1)

    variable value
1     Model1     4
2     Model1     4
3     Model1     3
4     Model1     2
5     Model1     3
6     Model1     3
7     Model2     4
8     Model2     4
9     Model2     2
10    Model2     2
11    Model2     3
12    Model2     3
13    Model3     5
14    Model3    NA
15    Model3     5
16    Model3     3
17    Model3     3
18    Model3     4
19    Model4     5
20    Model4    NA
21    Model4     5
22    Model4     3
23    Model4     3
24    Model4     4

Renamed the columns for ease:

names(df2)<-c("Model","Score")

Then calculate the proportions:

df3 <- as.data.frame(table(df2))
df3$prop<-df4$Freq/4*100

And finally, the plot:

ggplot(df3,aes(x=Model,y=prop,fill=as.factor(Score)))+
       geom_bar(stat="identity",position="dodge")+
       xlab("Models")+
       ylab("Prop. of Cases (%)")+
       ggtitle("Sample Data")+
       guides(fill=guide_legend(title="Scores"))+
       scale_fill_manual(values = c("2" = "lightblue", "3" = "mistyrose","4"="lightcyan","5"="lavender"))+
       theme_bw()

Sign up to request clarification or add additional context in comments.

6 Comments

I want the scores , i.e., 0,1,2,3,4,5 in the legend and the proportion in the y-axis
Edited my answer. Like that?
yes correct, but the y-axis should have the proportions,say for example in model1 2 occurs in 20% cases and similarly for other categories. One more question, will it be a good idea to have the row variable created in case I have 500K records?
The row variable isn't necessary unless you want to at some point refer to each value for each model based on its row position. If the order of the values under each model isn't relevant, then a row name is also likely to be irrelevant. Stand by on the proportions.
I tried the following: 1. created a seperate dataframe having two columns, viz. Score and Model 2. created a matix with the proportions mat <- table(Q$Score,Q$Model) mat <- round(prop.table(mat,margin=2)*100,2) 3. used barplot to plot : barplot(mat, beside = TRUE, ` col = c("lightblue", "mistyrose", "lightcyan", "lavender",` "cornsilk","green"), ` legend.text = rownames(mat), ylim = c(0, 40),main="Sample` Data", ` xlab="Models",ylab="Prop. of Cases (%)")` It worked
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.