nikki
nikki

Reputation: 239

Finding column Name from the data in r for 1's

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

Upvotes: 0

Views: 126

Answers (2)

Gregor Thomas
Gregor Thomas

Reputation: 145965

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>

Upvotes: 1

Roman Luštrik
Roman Luštrik

Reputation: 70653

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

Upvotes: 2

Related Questions