Demystifying the melt() Function in R

[This article was first published on Steve's Data Tips and Tricks, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.


The melt() function in the data.table package is an extremely useful tool for reshaping datasets in R. However, for beginners, understanding how to use melt() can be tricky. In this post, I’ll walk through several examples to demonstrate how to use melt() to move from wide to long data formats.

What is melting data?

Melting data refers to reshaping it from a wide format to a long format. For example, let’s say we have a dataset on student test scores like this:


scores <- data.table(
  student = c("Alice", "Bob", "Charlie"),
  math = c(90, 80, 85), 
  english = c(85, 90, 80)

   student  math english
    <char> <num>   <num>
1:   Alice    90      85
2:     Bob    80      90
3: Charlie    85      80

Here each subject is in its own column, with each student in a separate row. This is the wide format. To melt it, we convert it to long format, where there is a single value column and an identifier column for the variable:

melted_scores <- melt(scores, id.vars = "student", measure.vars = c("math", "english"))

   student variable value
    <char>   <fctr> <num>
1:   Alice     math    90
2:     Bob     math    80
3: Charlie     math    85
4:   Alice  english    85
5:     Bob  english    90
6: Charlie  english    80

Now there is one row per student-subject combination, with the subject in a new “variable” column. This makes it easier to analyze and plot the data.

How to melt data in R with data.table

The melt() function from data.table makes it easy to melt data. The basic syntax is:

melt(data, id.vars, measure.vars)


  • data: the data.table to melt
  • id.vars: the column(s) to use as identifier variables
  • measure.vars: the column(s) to unpivot into the value column

For example:


 WideTable <- data.table(
  Id = 1:3,
  Var1 = c(10, 20, 30),
  Var2 = c(100, 200, 300)  

melt(WideTable, id.vars = "Id", measure.vars = c("Var1", "Var2"))
      Id variable value
   <int>   <fctr> <num>
1:     1     Var1    10
2:     2     Var1    20
3:     3     Var1    30
4:     1     Var2   100
5:     2     Var2   200
6:     3     Var2   300

The id.vars define which column(s) to keep fixed, while the measure.vars are melted into key-value pairs.

Casting data back into wide format

Once data is in long format, you can cast it back into wide format using dcast() from data.table:

melted <- melt(WideTable, id.vars="Id") 

dcast(melted, Id ~ variable)
Key: <Id>
      Id  Var1  Var2
   <int> <num> <num>
1:     1    10   100
2:     2    20   200
3:     3    30   300

This flexibility allows for easy data manipulation as needed for analysis and visualization.

Final thoughts

The melt() function provides a simple yet powerful way to move between wide and long data formats in R. By combining melt() and dcast(), you can wrangle messy datasets into tidy forms for effective data analysis. So give it a try on your own datasets and see how it unlocks new possibilities! Let me know in the comments if you have any other melt() questions.

To leave a comment for the author, please follow the link and comment on their blog: Steve's Data Tips and Tricks. offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)