0

Here i want to add the column/'s in a dataframe and specifying the column name for which we found 1 in the main table.

e.g.

  1. SrNo 1, we have 1 for the column C only hence the ouput table would have only one column and the value for it would be C.

  2. SrNo 2, we have 1 for column B and D hence the ouput table should have 2 columns named as Ouput1,Ouput2 and the value for those would be B and D respectively.

i am able to identify that we can do this using below code and run this in a loop for all the rows, however it's not i want because of the performance issue.

Anyone has some good way to achieve this task

tableA <- data.frame(
  SR =  1:5,
  A = c(0, 0, 0, 1, 1),
  B = c(0, 1, 0, 1, 1),
  C = c(1, 0, 1, 1, 0),
  D = c(0, 1, 0, 1, 1),
  E = c(0, 1, 0, 0, 1))

colnames(tableA)[(which(tableA[1,] == 1))]

Table

enter image description here

Output should be like:

enter image description here

nikki
  • 239
  • 1
  • 12
  • Related, possible duplicate posts: for [matrix](https://stackoverflow.com/questions/44585712) and [data.table](https://stackoverflow.com/questions/36304404) – zx8754 Nov 29 '18 at 16:59

2 Answers2

2

How's this? I have conveniently left the "output" part as a separate table. Feel free to cbind it on your own.

tableB <- tableA
for (i in 2:ncol(tableB)) {
  cn <- colnames(tableB[, i, drop = FALSE])
  tableB[, i] <- ifelse(tableB[, i] == 1, cn, "") 
}

tableA$final_output <- apply(tableB[, -1], MARGIN = 1, FUN = function(x) {
  out <- trimws(paste(x, collapse = ""))
  paste(strsplit(out, "")[[1]], collapse = ",")
})

tableA

  SR A B C D E final_output
1  1 0 0 1 0 0            C
2  2 0 1 0 1 1        B,D,E
3  3 0 0 1 0 0            C
4  4 1 1 1 1 0      A,B,C,D
5  5 1 1 0 1 1      A,B,D,E
Roman Luštrik
  • 69,533
  • 24
  • 154
  • 197
1

Here's a simple to get the FinalOutput, and then use tidyr::separate to get the individual outputs in case those are needed.

nn = names(tableA)[-1]
tableA$FinalOutput = apply(tableA[-1] == 1, 1, function(x) paste(nn[x], collapse = ","))
tableA
  SR A B C D E FinalOutput
1  1 0 0 1 0 0           C
2  2 0 1 0 1 1       B,D,E
3  3 0 0 1 0 0           C
4  4 1 1 1 1 0     A,B,C,D
5  5 1 1 0 1 1     A,B,D,E

tidyr::separate(tableA,
                col = FinalOutput, 
                into = paste("Output", 1:(ncol(tableA) - 2), sep = "_"),
                sep = ",",
                remove = FALSE,
                fill = "right")   

  SR A B C D E FinalOutput Output_1 Output_2 Output_3 Output_4 Output_5
1  1 0 0 1 0 0           C        C     <NA>     <NA>     <NA>     <NA>
2  2 0 1 0 1 1       B,D,E        B        D        E     <NA>     <NA>
3  3 0 0 1 0 0           C        C     <NA>     <NA>     <NA>     <NA>
4  4 1 1 1 1 0     A,B,C,D        A        B        C        D     <NA>
5  5 1 1 0 1 1     A,B,D,E        A        B        D        E     <NA>
Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294
  • 1
    @nikki I'm glad you found this answer helpful. I saw you accepted another answer before I had the chance to post this (which was disappointing to me at the time...) and now you've switched to accepting my answer almost immediately. Let me suggest that you wait *a little longer* before accepting answers in general. Maybe, an hour after the first answer is posted. An answer may still come along that you like better than mine. – Gregor Thomas Nov 29 '18 at 14:56