Data Table R: molten or reshape data table without stacked variable column

76 views Asked by At

Data

str(DT)
Classes ‘data.table’ and 'data.frame':  6 obs. of  3b variables:
 $ A  : Factor w/ 6 levels "0","1","2","3",..: 1 2 3 4 5 6
 $ N  : num  13 11 10 5 1 1
 $ ID : Factor w/ 1 level "1": 1 1 1 1 1 1

I'd like to reshape this DT to the DT below. If I melt DT by melt.data.table(DT, id.vars = "ID", measure.vars = 1:2) I get a following wacky melted DT.

   ID  N     variable value
 1: 1 13         A     0
 2: 1 11         A     1
 3: 1 10         A     2
 4: 1  5         A     3
 5: 1  1         A     4
 6: 1  1         A     5
 7: 1 13         N    13
 8: 1 11         N    11
 9: 1 10         N    10
10: 1  5         N     5
11: 1  1         N     1
12: 1  1         N     1

My desired output is as follows. Basically, molten DT should have a variable (or new) column without stacked variable columns from an pre-molten DT

Desired Output

     ID   variable  value    N 
 1:   1     A        0      13
 2:   1     A        1      11
 3:   1     A        2      10
 4:   1     A        3       5  
 5:   1     A        4       1
 6:   1     A        5       1

I'd appreciate any pointers

Little late but here is an original data table:

   A  N  ID
1:   0 13   1
2:   1 11   1
3:   2 10   1
4:   3  5   1
5:   4  1   1
6:   5  1   1
3

There are 3 answers

0
Ronak Shah On BEST ANSWER

We can use pivot_longer from tidyr. Using @Rui Barradas' data.

tidyr::pivot_longer(dt1, cols = A, names_to = 'variable') %>%
   dplyr::select(ID,variable, value ,N)

# A tibble: 6 x 4
#  ID    variable value     N
#  <fct> <chr>    <fct> <dbl>
#1 1     A        0        13
#2 1     A        1        11
#3 1     A        2        10
#4 1     A        3         5
#5 1     A        4         1
#6 1     A        5         1
0
akrun On

If the input dataset is 6 row dataset, then we can create those columns as

library(data.table)
DT[, c('variable', 'value') := .('A', as.numeric(as.character(A)) -1)][, A := NULL][]
#     N ID variable value
#1: 13  1        A     0
#2: 11  1        A     1
#3: 10  1        A     2
#4:  5  1        A     3
#5:  1  1        A     4
#6:  1  1        A     5

data

DT <- data.table(A = factor(1:6), N = c(13, 11, 10, 5, 1, 1), ID = 1)
0
Rui Barradas On

This solution uses data.table::melt, like in the question. But unlike in the question, all variables that are not to be stacked are in argument id.vars.

library(data.table)

melt(dt1, id.vars = c("ID", "N"))
#   ID  N variable value
#1:  1 13        A     0
#2:  1 11        A     1
#3:  1 10        A     2
#4:  1  5        A     3
#5:  1  1        A     4
#6:  1  1        A     5

Data

dt1 <- data.table(A = factor(0:5),
                  N = c(13, 11, 10, 5, 1, 1),
                  ID = factor(1))