1

I have a dataframe like the following one:

A <- data.frame(Red = c(1,0,0,0),
                Blue = c(0,1,0,1),
                Yellow = c(0,0,1,0))

I would like to combine the information in order to get this column:

B <- data.frame(Colour = c("Red", "Blue", "Yellow", "Blue"))

that is, the name of the column where a 1 appears on it.

Julian
  • 6,586
  • 2
  • 9
  • 33
R18
  • 1,476
  • 1
  • 8
  • 17

3 Answers3

5

You could use max.col to subset names of A.

names(A)[max.col(A)]
#[1] "Red"    "Blue"   "Yellow" "Blue"

Or using which with arr.ind.

names(A)[which(t(A == 1), TRUE)[,1]]
#[1] "Red"    "Blue"   "Yellow" "Blue" 
GKi
  • 37,245
  • 2
  • 26
  • 48
0

Here is a bit complicated base R option

> names(A)[na.omit(c(t(col(A) * A^NA)))]
[1] "Red"    "Blue"   "Yellow" "Blue"
ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81
0

GKi's max.col solution seems best for how short it is but here are a few others anyways. They each generate the vector c(1, 2, 3, 2) and then subscript names(A) by it.

names(A)[as.matrix(A) %*% seq_along(A)]

names(A)[apply(A == 1, 1, which)]

names(A)[apply(A, 1, which.max)]

names(A)[rowSums(A * col(A))]
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341