Take a more general case of irregular results:
dat <- structure(list(M1 = c(0L, 1L, 0L), M2 = c(1L, -1L, 1L), M3 = -1:1,
M4 = c(1L, 0L, 0L)), .Names = c("M1", "M2", "M3", "M4"),
class = "data.frame", row.names = c("2", "5", "7"))
> dat
M1 M2 M3 M4
2 0 1 -1 1
5 1 -1 0 0
7 0 1 1 0
An internal approximating "loop" builds a logical set of vectors. Since R is column oriented, the second level of processing is performed on the columns. The external “loop” applied extracts the corresponding elements from the code names:
apply( apply(dat,1, as.logical) , 2, function(ll) colnames(dat)[ll] )
$`2`
[1] "M2" "M3" "M4"
$`5`
[1] "M1" "M2"
$`7`
[1] "M2" "M3"
You could also extract the version of the array indicator from which (), and then process the results:
> which(dat != 0, arr.ind=TRUE)
row col
5 2 1
2 1 2
5 2 2
7 3 2
2 1 3
7 3 3
2 1 4