Search code examples
rdataframedplyrtidyr

How can I convert the format of my dataframe into a new transposed format in R?


I would like to convert my dataframe, df1, to the format shown in df2. How can I do this in an efficient manner without hard-coding & while using R libraries?

df1 <- data.frame(
  A = c(1, 5, 3, 4),
  B = c(5, 9, 4, 7),
  C = c(6, 8, 9, 10),
  D = c(3, 4, 8, 3),
  E = c(7, 2, 5, 5),
  F = c(4, 1, 1, 9)
)

df2 <- data.frame(
  attribute_1 =  c(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0),
  attribute_2 =  c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  attribute_3 =  c(0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0),
  attribute_4 =  c(0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0),
  attribute_5 =  c(0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0),
  attribute_6 =  c(0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  attribute_7 =  c(0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0),
  attribute_8 =  c(0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0),
  attribute_9 =  c(0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1),
  attribute_10 = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0)
)
##       value:    1  5  6  3  7  4  5  9  8  4  2  1  3  4  9  8  5  1  4  7 10  3  5  9
##     df1 row:    1  1  1  1  1  1  2  2  2  2  2  2  3  3  3  3  3  3  4  4  4  4  4  4

Solution

  • You can try

    df3 <- as.data.frame(matrix(0, prod(dim(df1)), max(df1)))
    df3[cbind(1:nrow(df3), c(t(df1)))] <- 1
    

    df3 is what you want. You can transform the above code into a one-liner:

    df3 <- `[<-`(as.data.frame(matrix(0, nr <- prod(dim(df1)), max(df1))),
                 cbind(1:nr, c(t(df1))), value = 1)
    

    Check
    all.equal(df2, df3, check.attributes = FALSE)
    # [1] TRUE