Search code examples
rdataframereshapemelt

How to reshape dataframe to generate two-column values (R programming)


I have a data.frame that looks like this:

  name1 feat   x  y perc.x perc.y
1   foo    z 100 10    0.1      1
2   bar    w 200 20    0.2      2
3   qux    x 300 30    0.3      3
4   qux    y 400 40    0.4      4
5   bar    v 500 50    0.5      5

It is generated with the following code:

name1 <- c("foo","bar","qux","qux","bar")
 feat <- c("z","w","x","y","v")
 x <- c(100,200,300,400,500)
 y <- c(10,20,30,40,50)
 perc.x <- c(0.1,0.2,0.3,0.4,0.5)
 perc.y <- c(1,2,3,4,5)

 df <- data.frame(name1,feat,x,y,perc.x,perc.y)
 df

How can I create a melted data like this:

    name1 feat variable value value2.perc
1    foo    z        x 100.0   0.1
2    bar    w        x 200.0   0.2
3    qux    x        x 300.0   0.3
4    qux    y        x 400.0   0.4
5    bar    v        x 500.0   0.5
6    foo    z        y  10.0   1
7    bar    w        y  20.0   2
8    qux    x        y  30.0   3
9    qux    y        y  40.0   4
10   bar    v        y  50.0   5

I tried this but failed:

   library(reshape2)
    melt(df)

Solution

  • Solution with base R, Using reshape :

     reshape(df,direction='long', varying=list(c(3, 4), c(5, 6)))
        name1 feat time   x perc.x id
    1.1   foo    z    1 100    0.1  1
    2.1   bar    w    1 200    0.2  2
    3.1   qux    x    1 300    0.3  3
    4.1   qux    y    1 400    0.4  4
    5.1   bar    v    1 500    0.5  5
    1.2   foo    z    2  10    1.0  1
    2.2   bar    w    2  20    2.0  2
    3.2   qux    x    2  30    3.0  3
    4.2   qux    y    2  40    4.0  4
    5.2   bar    v    2  50    5.0  5
    

    Maybe you should work a little bit time variable.

    EDIT better, thanks to @mnel brilliant comment :

    reshape(df,direction='long', varying=list(c(3, 4), c(5, 6)),
            ,v.names = c('value','perc'), times = c('x','y'))
    
        name1 feat time value perc id
    1.x   foo    z    x   100  0.1  1
    2.x   bar    w    x   200  0.2  2
    3.x   qux    x    x   300  0.3  3
    4.x   qux    y    x   400  0.4  4
    5.x   bar    v    x   500  0.5  5
    1.y   foo    z    y    10  1.0  1
    2.y   bar    w    y    20  2.0  2
    3.y   qux    x    y    30  3.0  3
    4.y   qux    y    y    40  4.0  4
    5.y   bar    v    y    50  5.0  5