I think you want to know which column (name) includes the value 1
.
tmp <- colSums(dat == 1) > 0
names(tmp[tmp])
# [1] "A"
Walk-through:
The ==
returns a matrix with per-position matches:
dat == 1
# Name A B C D E
# [1,] FALSE TRUE FALSE FALSE FALSE FALSE
# [2,] FALSE FALSE FALSE FALSE FALSE FALSE
# [3,] FALSE FALSE FALSE FALSE FALSE FALSE
# [4,] FALSE FALSE FALSE FALSE FALSE FALSE
colSums(.) > 0
tells us which column has at least one TRUE
:
colSums(dat == 1) > 0
# Name A B C D E
# FALSE TRUE FALSE FALSE FALSE FALSE
... and then we take the name of the names found. If none are found, it will return an empty vector:
names(tmp[tmp])
# character(0)
The only gotcha I can think of here is if you are doing high-precision floating-point comparison, in which case IEEE-754 comes into play (see Why are these numbers not equal?, Is floating point math broken?, and https://en.wikipedia.org/wiki/IEEE_754). For that, consider a test of inequality with tolerance instead of a strict test of equality.
This requires that we only look at numeric columns.
isnum <- sapply(dat, is.numeric)
isnum
# Name A B C D E
# FALSE TRUE TRUE TRUE TRUE TRUE
tmp <- colSums(abs(dat[,isnum] - 1) < 1e-5) > 0
# ,^^^^^ ^^^^^^^^^^^.
# subset the data --'
# ... and a test of inequality within tolerance
names(tmp[tmp])
# [1] "A"