Reputation: 1353
Let say I have below matrix
Mat = matrix(rnorm(25), 5, 5, dimnames = list(LETTERS[1:5], letters[1:5]))
Now I want to subset this matrix based on below vector
as column
Vec = c("a", "c", "x", "b", "y")
Mat[, Vec]
With this I get below error -
Error in Mat[, Vec] : subscript out of bounds
I know this error is by R
's design. However I want to make it work, such that the elements corresponding to unknown column names would come as NA
Is there any way to achieve this in R
?
Thanks for your time.
Upvotes: 1
Views: 381
Reputation: 503
How about using match
?
Mat = matrix(rnorm(25), 5, 5, dimnames = list(LETTERS[1:5], letters[1:5]))
Vec = c("a", "c", "x", "b", "y")
Mat[, match(Vec, colnames(Mat))]
Which outputs
> Mat[, match(Vec, colnames(Mat))] a c <NA> b <NA> A 0.2427570 -0.4060827 NA 0.4698090 NA B 1.5994373 -0.5916460 NA -0.4074645 NA C 0.2120962 -1.4829029 NA -1.0006933 NA D -0.6991751 0.6605346 NA -0.6403174 NA E -0.2155225 0.8447741 NA -0.8743710 NA
Upvotes: 1
Reputation: 886928
We can use intersect
to take into account of the column names that are not present in the matrix
but only in the vector
mat2 <- Mat[, intersect(Vec, colnames(Mat))]
-output
mat2
a c b
A 0.28358265 0.4285490 -0.64482025
B 0.04228662 -0.7667130 -0.19550185
C -0.57197755 -1.8296791 -0.76012324
D -0.72591283 0.2336603 0.45026240
E -1.13775762 -1.9874356 -0.02215211
If we need to create new columns
nm1 <- setdiff(Vec, colnames(Mat))
nm2 <- setNames(rep(NA, length(nm1)), nm1)
cbind(mat2, t(nm2)[rep(1, nrow(mat2)),])
An easier option would be
Vec <- letters[1:3]
mat2 <- matrix(NA, nrow(Mat), length(Vec),
dimnames = list(row.names(Mat), Vec))
v1 <- intersect(colnames(Mat), Vec)
mat2[,v1] <- Mat[, v1]
mat2
# a b c
#A -0.3811391 -0.7600103 -1.33100900
#B 0.4015464 1.2833597 1.06669817
#C 0.1582268 0.1562223 0.61765738
#D 1.5972361 1.4957370 0.45159383
#E 0.1970359 -0.8246555 0.03037087
Or with the original Vec
Vec = c("a", "c", "x", "b", "y")
mat2 <- matrix(NA, nrow(Mat), length(Vec),
dimnames = list(row.names(Mat), Vec))
v1 <- intersect(colnames(Mat), Vec)
mat2[,v1] <- Mat[, v1]
mat2
# a c x b y
#A -0.3811391 -1.33100900 NA -0.7600103 NA
#B 0.4015464 1.06669817 NA 1.2833597 NA
#C 0.1582268 0.61765738 NA 0.1562223 NA
#D 1.5972361 0.45159383 NA 1.4957370 NA
#E 0.1970359 0.03037087 NA -0.8246555 NA
Upvotes: 0