Search code examples
rreshape2

Melt output unexpected , all 0 values


Here is the following dataframe with only one row. In most cases the dataframes comes with many rows but came across one special case where i had only one row.

library(reshape2)
  temp <- structure(list(D0 = 0, D2 = 0, D14 = 0, D14 = 0, D14 = 8.1210458037618, 
D14 = 16.4531432694911, D7 = 0, D0 = 0, D0 = 0, D14 = 0, 
D0 = 0, D14 = 0, D7 = 12.9742361276578, D0 = 9.38010319990484, 
D14 = 6.35545262547878, D2 = 0, D14 = 1.35569798573994, D7 = 13.340409178823, 
D2 = 9.36805417941219, D2 = 15.432692223528, D14 = 0, D0 = 0, 
D14 = 0, D7 = 6.09471835659014, D7 = 0, D2 = 0, D2 = 7.67135586471563, 
D14 = 28.1073822991286, D14 = 0, D2 = 7.58819062711938, D7 = 0, 
D0 = 1.5735281713825, D0 = 0, D7 = 1.86165503278318, D7 = 5.35571350639711, 
D2 = 2.47400939410094, D14 = 21.3059220365934, D0 = 0, D7 = 8.69569412672166, 
D0 = 0, D14 = 0, D2 = 0.531180424946459, D0 = 3.42867314180642, 
D0 = 0, D2 = 0, D14 = 0, D7 = 0.775767964360802, D0 = 2.59382750787083, 
D7 = 0.600664752805997, D2 = 7.35512462974749, D14 = 2.30110773119572, 
D7 = 3.23850639812659, D0 = 0, D7 = 0.958981742285896, D2 = 3.84623208865623, 
D2 = 2.70323099283864, D7 = 1.65260222673919, D0 = 0, D2 = 4.00782923944589, 
D7 = 5.65802187007992, D0 = 0, D0 = 0, D7 = 0, phylum = structure(1L, .Label = "Acidobacteria", class = "factor")), row.names = 14L, class = "data.frame")

    > temp
       D0 D2 D14 D14      D14      D14 D7 D0 D0 D14 D0 D14       D7       D0      D14 D2      D14       D7       D2
    14  0  0   0   0 8.121046 16.45314  0  0  0   0  0   0 12.97424 9.380103 6.355453  0 1.355698 13.34041 9.368054
             D2 D14 D0 D14       D7 D7 D2       D2      D14 D14       D2 D7       D0 D0       D7       D7       D2
    14 15.43269   0  0   0 6.094718  0  0 7.671356 28.10738   0 7.588191  0 1.573528  0 1.861655 5.355714 2.474009
            D14 D0       D7 D0 D14        D2       D0 D0 D2 D14       D7       D0        D7       D2      D14       D7 D0
    14 21.30592  0 8.695694  0   0 0.5311804 3.428673  0  0   0 0.775768 2.593828 0.6006648 7.355125 2.301108 3.238506  0
              D7       D2       D2       D7 D0       D2       D7 D0 D0 D7        phylum
    14 0.9589817 3.846232 2.703231 1.652602  0 4.007829 5.658022  0  0  0 Acidobacteria

I´m running a melt function to aggregate data by phylum as follows (this will be next used to plot data with ggplot)

> reshape2::melt(temp,id="phylum")
         phylum variable value
1 Acidobacteria       D0     0
2 Acidobacteria       D2     0
3 Acidobacteria      D14     0
4 Acidobacteria       D7     0

How comes i only get 0 values ??? I would expect the sum of all D0 for Acidobacteria and all D2 for Acidobacteria and so on

> sum(temp[,colnames(temp) =="D0"]) 
[1] 16.97613

1 Acidobacteria       D0     16.97613
2 Acidobacteria       D2     60.9779
3 Acidobacteria      D14     83.99975
4 Acidobacteria       D7     83.99975

Solution

  • The output you're looking for requires a three-stage process: 1) rename the variables, 2) melt the data, 3) aggregate the data. We do this with the dplyr and tidyr packages (or reshape2 if you're keen on that package).

    library(dplyr)
    library(tidyr)
    
    temp <- structure(list(D0 = 0, D2 = 0, D14 = 0, D14 = 0, D14 = 8.1210458037618, 
                           D14 = 16.4531432694911, D7 = 0, D0 = 0, D0 = 0, D14 = 0, 
                           D0 = 0, D14 = 0, D7 = 12.9742361276578, D0 = 9.38010319990484, 
                           D14 = 6.35545262547878, D2 = 0, D14 = 1.35569798573994, D7 = 13.340409178823, 
                           D2 = 9.36805417941219, D2 = 15.432692223528, D14 = 0, D0 = 0, 
                           D14 = 0, D7 = 6.09471835659014, D7 = 0, D2 = 0, D2 = 7.67135586471563, 
                           D14 = 28.1073822991286, D14 = 0, D2 = 7.58819062711938, D7 = 0, 
                           D0 = 1.5735281713825, D0 = 0, D7 = 1.86165503278318, D7 = 5.35571350639711, 
                           D2 = 2.47400939410094, D14 = 21.3059220365934, D0 = 0, D7 = 8.69569412672166, 
                           D0 = 0, D14 = 0, D2 = 0.531180424946459, D0 = 3.42867314180642, 
                           D0 = 0, D2 = 0, D14 = 0, D7 = 0.775767964360802, D0 = 2.59382750787083, 
                           D7 = 0.600664752805997, D2 = 7.35512462974749, D14 = 2.30110773119572, 
                           D7 = 3.23850639812659, D0 = 0, D7 = 0.958981742285896, D2 = 3.84623208865623, 
                           D2 = 2.70323099283864, D7 = 1.65260222673919, D0 = 0, D2 = 4.00782923944589, 
                           D7 = 5.65802187007992, D0 = 0, D0 = 0, D7 = 0, phylum = structure(1L, .Label = "Acidobacteria", class = "factor")), row.names = 14L, class = "data.frame")
    
    # Append a suffix to the column names to make them unique
    names(temp) = paste0(names(temp), '_', 1:ncol(temp))
    # Melt the data
    temp = gather(temp, key='variable', value='value', -phylum_64)
    # Could alternatively use melt(temp, id='phylum_64')
    # Remove the suffixes from the column names
    temp$variable = gsub('_\\d+', '', temp$variable)
    # Group by the prior column names and sum the values
    temp = temp %>%
        group_by(variable) %>%
        summarise(value = sum(value))
    
      variable    value
    1       D0 16.97613
    2      D14 83.99975
    3       D2 60.97790
    4       D7 61.20697