Skip to content

Solving: ggplot2 doesn’t know how to deal with data of class matrix

If you are new to ggplot2, then you probably got this error too. R is like Perl, you have a lot of ways to solve the same task.

I tried to solve this error for almost one week. There is a simple solution I found; Structure. As defined in R’s manual:  ‘structure’ returns the given object with further attributes set.

The following data is a sample of DNS query type A, PTR and MX. The separator is tab (“\t”). If you are lazy, the the file here.

         A      PTR    MX
hour1    123    125    198
hour2    345    349    127

Reading data:
mysample = read.csv('sample.csv', sep="\t")

Creating a Structure.
If you have more doubts about Structure, please take a look at [1]. In the original sample, we have two lines and three columns, therefore when using Structure, you may also need keep this configuration.
me = structure( c(mysample$A, mysample$PTR, mysample$MX) ,.Dim=c(2,3))

If you print ‘me’ object, you will get the following content:

     [,1] [,2] [,3]
[1,]  123  125  198
[2,]  345  349  127

Now you should set the header name or you can create a structure defining headers on the fly.
time = c("hour1", "hour2")
qname = c("A","PTR", "MX")
me = structure( c(mysample$A, mysample$PTR, mysample$MX) ,.Dim=c(2,3) ,.Dimnames=list( c(time), c(qname) ))

Good. ‘me’ object has been properly defined. It is time to create a data frame to ggplot plot ;). You must use melt() and then rename what melt() done with your data.
me.df = melt(me)
X1  X2 value
1 hour1   A   123
2 hour2   A   345
3 hour1 PTR   125
4 hour2 PTR   349
5 hour1  MX   198
6 hour2  MX   127

Renaming the mess:

me.df = rename(me.df, c(X1=”Hour”, X2=”Qtype”))
Hour Qtype value
1 hour1     A   123
2 hour2     A   345
3 hour1   PTR   125
4 hour2   PTR   349
5 hour1    MX   198
6 hour2    MX   127

Time to Plot (finally)
a = ggplot(me.df, aes(x = Hour, y = value, fill = Qtype))
a + geom_bar(stat = "identity",  position = "stack")

If you follow everything and no got no error, you should have this plot:

You can add many parameters such Title, Y label with opts(). Please take a look at [2] and [3].

The following lines are the full source code used here.
mysample = read.csv('sample.csv', sep="\t")
time = c("hour1", "hour2")
qname = c("A","PTR", "MX")
me = structure( c(mysample$A, mysample$PTR, mysample$MX) ,.Dim=c(2,3) ,.Dimnames=list( c(time), c(qname) ))
me.df = melt(me)
me.df = rename(me.df, c(X1="Hour", X2="Qtype"))
a = ggplot(me.df, aes(x = Hour, y = value, fill = Qtype))
a + geom_bar(stat = "identity",  position = "stack")

2 –
3 –



  1. vinsent vinsent

    Nice posting, this was useful for me one of the plotting.

  2. urmay shah urmay shah

    i am using whole file of latitude in matrix form.what i want to do is to cut the particular region for that latitude file; here i want to cut lat region of 20 to 25 .
    and i want to plot that region in graph .please help me out doing this.

    • Bring us a sample from this matrix, and lets see I can help.


  3. Stefanie Stefanie

    Hi! Thanks for this wonderful explanation. I’m fairly new to plotting in R and found this tutorial super helpful. I normally have data tables with many columns (sometimes up to 50), so I was wondering if there’s any way to facilitate/automate this step:

    me = structure( c(mysample$A, mysample$PTR, mysample$MX) ,.Dim=c(2,3) ,.Dimnames=list( c(time), c(qname) ))

    where you indicate all columns using mysample$NAMEOFCOLUMN

    Could you please tell me if you know of a way to automate the input of these column names? Thank you so much in advance!


    • Hi Stefanie,

      Well, I never had such demand, but I would write some loop to read my table and use `paste` to generate a new var with this content. The result of this loop would be a set of ‘mysample$NAMEOFCOLUMN1` `mysample$NAMEOFCOLUMN2 ….`

      I have done this long time ago, but something like that:

      x < - 1:10 for(i in seq_along(x)){ assign(paste('X', i, sep=''), x[i]) }

      • Stefanie Stefanie

        Hi! Thanks for your fast reply!

        Let’s say I named my dataframe dat.

        If I use

        for(i in seq_along(dat)){
        assign(paste(‘test’, i, sep=”), dat[i])

        then I get new dataframes that are called test1, test2, … test10, each of which contains a single column of my original data frame, and unfortunately not one which contains the titles of the columns. So I’m afraid I’m misunderstanding your suggestion.

        I’ll also try to rephrase my question, in case I haven’t been clear. I basically just want to use

        me = structure( c(dat$A, dat$PTR, dat$MX) ,.Dim=c(2,3) ,.Dimnames=list( c(time), c(qname) ))

        without having to fill out the dat$A, dat$PTR etc. manually, because that’s a lot of work if you have to do it for more than 5 columns.

        I’m sorry if my request doesn’t make any sense. The reason I’m asking is that I have several tables each with varying amounts of columns headers, some of which have 10 columns, others of which have 50. If I can automate the dat$A, dat$PTR retrieval, then I could automate the structuring of all of these tables.

        Thanks again so much for your help, I really appreciate it!


  4. Stefanie Stefanie

    I’ve created a solution that is probably not the most elegant, but it seems to be working well for me.

    I upload the data and call it dat. Then I create the dat$colnames as follows:

    ## add the dat$ in front of each colname and add the comma after it
    ## remove the first column header
    ## transpose to get a row instead of a column

    If I then view (cn), I get a row with the dat$colnames, e.g. like this:
    A dat$ GRP75 , dat$ LAMA5 , dat$ LAMC1 , dat$ MTNB , dat$ GRP78 , dat$ GLYM , dat$ HSP7C , dat$ NCCRP1 , dat$ GFP

    Then I can just copy-paste them into the structure function. It's not perfect, but it works. Thanks for your help!


    • I was coding similar code :D you were faster!

      names = c()
      for(i in colnames(mysample)){
      names[index] = paste(‘mysample$’,i, sep=””);
      index = index + 1

      I guess your solution is better :D

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload the CAPTCHA.