Extract column names for each value in column in matrix in R

Viewed 70

I have following matrix:

r1 <- c("M","A","T","D","T","Y")
r2 <- c("M","A","G","G","T", "J")
r3 <- c("M","B","H","G","T", "Y")
r4 <- c("M","B","G","G","X", "Y")
r5<- c("F","A","H","D","T", "Y")
n.mat <- rbind(r1,r2,r3,r4,r5)
n.mat<-as.data.frame(n.mat)

I would like to extract a column name for each unique value in a column as a vector. At the moment the column names are: V1 V2 V3 V4 V5 V6 The output should look like this:

V1_M V1_F V2_A V2_B V3_T V3_G V3_H V4_D V4_G V5_T V5_X V6_Y V6_J

The order should be in the order as the unique values occur in the column from top to bottom.

My code:

apply(n.mat,2,FUN = function(x) paste(unique(x), seq_along(x), sep = '_'))

But this converts only the values in the matrix and not the columnnames and neither outputs it as a vector.

2 Answers

We may use paste in a vectorized way by replicating the column names with col index and then get the unique after pasteing with the values of the n.mat (it is a data.frame after as.data.frame - so we used unlist)

unique(paste(colnames(n.mat)[col(n.mat)], unlist(n.mat), sep="_"))

-output

[1] "V1_M" "V1_F" "V2_A" "V2_B" "V3_T" "V3_G" "V3_H" "V4_D"
[9] "V4_G" "V5_T" "V5_X" "V6_Y" "V6_J"

Or if need a loop, use Map

unlist(Map(function(x, y) unique(paste(y, x, sep = "_")), 
     unname(n.mat), names(n.mat)))

The apply wouldn't work here as the names for each column will be the row.names attribute (even if change the OP's code to names)

We could use Map as akrun already suggested and paste the names to the values. After that retrieve the unique values as vector:

n.mat[] <- Map(paste, names(n.mat), n.mat, sep = '_')
as.character(unique(unlist(n.mat)))

output:

 [1] "V1_M" "V1_F" "V2_A" "V2_B" "V3_T" "V3_G" "V3_H" "V4_D" "V4_G" "V5_T"
[11] "V5_X" "V6_Y" "V6_J"
Related