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.
CodePudding user response:
We may use paste
in a vectorized way by rep
licating the column names with col
index and then get the unique
after paste
ing 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
)
CodePudding user response:
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"