2

I have a logical matrix as follows:

     none ants beeswasps grasshoppers flies maggots beetles other
 [1,] T    F    F         F            F     F       F       F    
 [2,] T    F    F         F            F     F       F       F    
 [3,] T    F    F         F            F     F       F       F    
 [4,] T    F    F         F            F     F       F       F    
 [5,] T    F    F         F            F     F       F       F    
 [6,] T    F    F         F            F     F       F       F    
 [7,] F    F    T         F            F     F       T       T    

I want to change the elements with the respective column name when the element is true, and no text othewise. So, the resultant matrix would be:

      none ants beeswasps grasshoppers flies maggots beetles other
 [1,] none                                   
 [2,] none                                   
 [3,] none                                 
 [4,] none                                     
 [5,] none                                   
 [6,] none                               
 [7,]           beeswasps                          beetles    other    

This is a large matrix with many T/F values so a robust method is needed, not just creating another matrix to look like the one I want.

Here is a snippet

C = matrix( 
c(T,T,T,T,T,T,F,F,F,F,F,F,F,F,F,F,F,F,F,F,T,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,T,F,F,F,F,F,F,T), 
  nrow=7, ncol=8) 
colnames(C) <- c("none", "ants", "beeswasps", "grasshoppers", "flies", "maggots", "beetles", "other")
989
  • 12,579
  • 5
  • 31
  • 53
Maxwell Chandler
  • 626
  • 8
  • 18

3 Answers3

2

I think this would do the job:

for (i in colnames(m)){
  m[, i] <- ifelse(m[, i], i, "")
}

Change "" above (eg with NA) if you want something else to fill the "no entry" cases.


Here is a reproducible example that mimics your matrix:

m <- structure(c(FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE), .Dim = c(10L, 8L), .Dimnames = list(NULL, c("none", "ants", "beeswasps", "grasshoppers", "flies", "maggots", "beetles", "other")))

m before:

> m
none  ants beeswasps grasshoppers flies maggots beetles other
[1,] FALSE FALSE     FALSE        FALSE FALSE    TRUE   FALSE FALSE
[2,] FALSE FALSE     FALSE         TRUE FALSE    TRUE   FALSE FALSE
[3,]  TRUE FALSE     FALSE        FALSE  TRUE   FALSE   FALSE FALSE
[4,]  TRUE FALSE     FALSE        FALSE FALSE   FALSE    TRUE FALSE
[5,] FALSE  TRUE     FALSE        FALSE FALSE    TRUE   FALSE FALSE
[6,] FALSE FALSE     FALSE         TRUE  TRUE   FALSE   FALSE FALSE
[7,] FALSE FALSE     FALSE         TRUE FALSE   FALSE   FALSE FALSE
[8,] FALSE FALSE     FALSE        FALSE FALSE   FALSE   FALSE FALSE
[9,]  TRUE FALSE     FALSE        FALSE FALSE   FALSE   FALSE FALSE
[10,] FALSE FALSE     FALSE         TRUE FALSE   FALSE   FALSE FALSE

m after:

> m
none   ants   beeswasps grasshoppers   flies   maggots   beetles   other
[1,] ""     ""     ""        ""             ""      "maggots" ""        ""   
[2,] ""     ""     ""        "grasshoppers" ""      "maggots" ""        ""   
[3,] "none" ""     ""        ""             "flies" ""        ""        ""   
[4,] "none" ""     ""        ""             ""      ""        "beetles" ""   
[5,] ""     "ants" ""        ""             ""      "maggots" ""        ""   
[6,] ""     ""     ""        "grasshoppers" "flies" ""        ""        ""   
[7,] ""     ""     ""        "grasshoppers" ""      ""        ""        ""   
[8,] ""     ""     ""        ""             ""      ""        ""        ""   
[9,] "none" ""     ""        ""             ""      ""        ""        ""   
[10,] ""     ""     ""        "grasshoppers" ""      ""        ""        ""  
Community
  • 1
  • 1
Vincent Bonhomme
  • 7,235
  • 2
  • 27
  • 38
1

For each row x, you want the result row ifelse(x, colnames(C), NA). Coding this in an apply gives:

> t(apply(C, 1, function(x) ifelse(x, colnames(C), NA)))
     none   ants beeswasps   grasshoppers flies maggots beetles   other  
[1,] "none" NA   NA          NA           NA    NA      NA        NA     
[2,] "none" NA   NA          NA           NA    NA      NA        NA     
[3,] "none" NA   NA          NA           NA    NA      NA        NA     
[4,] "none" NA   NA          NA           NA    NA      NA        NA     
[5,] "none" NA   NA          NA           NA    NA      NA        NA     
[6,] "none" NA   NA          NA           NA    NA      NA        NA     
[7,] NA     NA   "beeswasps" NA           NA    NA      "beetles" "other"
Matthew Lundberg
  • 42,009
  • 6
  • 90
  • 112
  • This solution works because the matrix is composed of T and F correct? If the matrix was a collection of 2s and 4s and I wanted the colnames to replace 2s and the 4s to stay it would require more coding correct? This is a nice solution. – Maxwell Chandler Jun 03 '16 at 20:54
  • @MaxwellChandler That is correct. Coding `x==TRUE` is redundant, but `x==2` would not be so. – Matthew Lundberg Jun 03 '16 at 21:20
0

Or what you could do completely vectorized (without any loop or apply family functions):

> m
       # none  ants beeswasps grasshoppers flies maggots beetles other
 # [1,] FALSE FALSE     FALSE        FALSE FALSE    TRUE   FALSE FALSE
 # [2,] FALSE FALSE     FALSE         TRUE FALSE    TRUE   FALSE FALSE
 # [3,]  TRUE FALSE     FALSE        FALSE  TRUE   FALSE   FALSE FALSE
 # [4,]  TRUE FALSE     FALSE        FALSE FALSE   FALSE    TRUE FALSE
 # [5,] FALSE  TRUE     FALSE        FALSE FALSE    TRUE   FALSE FALSE
 # [6,] FALSE FALSE     FALSE         TRUE  TRUE   FALSE   FALSE FALSE
 # [7,] FALSE FALSE     FALSE         TRUE FALSE   FALSE   FALSE FALSE
 # [8,] FALSE FALSE     FALSE        FALSE FALSE   FALSE   FALSE FALSE
 # [9,]  TRUE FALSE     FALSE        FALSE FALSE   FALSE   FALSE FALSE
# [10,] FALSE FALSE     FALSE         TRUE FALSE   FALSE   FALSE FALSE

w=which(m==T, arr.ind = TRUE)[,2]
m[m==T]=colnames(m[,w])
m[m==F]=""

> m
      # none   ants   beeswasps grasshoppers   flies   maggots   beetles   other
 # [1,] ""     ""     ""        ""             ""      "maggots" ""        ""   
 # [2,] ""     ""     ""        "grasshoppers" ""      "maggots" ""        ""   
 # [3,] "none" ""     ""        ""             "flies" ""        ""        ""   
 # [4,] "none" ""     ""        ""             ""      ""        "beetles" ""   
 # [5,] ""     "ants" ""        ""             ""      "maggots" ""        ""   
 # [6,] ""     ""     ""        "grasshoppers" "flies" ""        ""        ""   
 # [7,] ""     ""     ""        "grasshoppers" ""      ""        ""        ""   
 # [8,] ""     ""     ""        ""             ""      ""        ""        ""   
 # [9,] "none" ""     ""        ""             ""      ""        ""        ""   
# [10,] ""     ""     ""        "grasshoppers" ""      ""        ""        ""  
989
  • 12,579
  • 5
  • 31
  • 53