Reputation: 345
Suppose I have a matrix rmatrix
defined below:
set.seed(10)
rmatrix <- matrix(sample(0:100, 16), ncol=4)
dimnames(rmatrix) <- list(rownames(rmatrix, do.NULL = FALSE,
prefix = "row"), colnames(rmatrix, do.NULL = FALSE, prefix = "col"))
rmatrix
col1 col2 col3 col4
row1 51 8 57 10
row2 30 21 39 52
row3 42 26 59 31
row4 67 25 100 36
A dataframe df
stores some combinations of the row and column names of rmatrix
:
df <- data.frame(r = c('row1', 'row1', 'row3', 'row4', 'row4', 'row4'),
c = c('col2', 'col4', 'col3', 'col3', 'col1', 'col2'))
df
r c
1 row1 col2
2 row1 col4
3 row3 col3
4 row4 col3
5 row4 col1
6 row4 col2
How to change any element in rmatrix
to NA
if its names are not in df
? Thanks!
Upvotes: 0
Views: 450
Reputation: 32538
out = replace(rmatrix*NA, as.matrix(df), rmatrix[as.matrix(df)])
out
# col1 col2 col3 col4
#row1 NA 8 NA 10
#row2 NA NA NA NA
#row3 NA NA 59 NA
#row4 67 25 100 NA
The following would work even when rmatrix
is made of characters
replace(replace(rmatrix, TRUE, NA), as.matrix(df), rmatrix[as.matrix(df)])
Upvotes: 3
Reputation: 886938
We can do this directly based on setdiff
library(dplyr)
rmatrix[as.matrix(setdiff(data.frame(r = rownames(rmatrix)[row(rmatrix)],
c= colnames(rmatrix)[col(rmatrix)]), df))] <- NA
rmatrix
# col1 col2 col3 col4
#row1 NA 8 NA 10
#row2 NA NA NA NA
#row3 NA NA 59 NA
#row4 67 25 100 NA
Or another option is to create a new matrix of NAs and then fill it with values based on the index in 'df'
m1 <- sapply(df, function(x) as.numeric(gsub("\\D+", "", x)))
rmatrix2 <- matrix(NA, nrow = nrow(rmatrix), ncol = ncol(rmatrix),
dimnames = dimnames(rmatrix))
rmatrix2[m1] <- rmatrix[m1]
rmatrix2
# [,1] [,2] [,3] [,4]
#[1,] NA 8 NA 10
#[2,] NA NA NA NA
#[3,] NA NA 59 NA
#[4,] 67 25 100 NA
Or we can create a sparseMatrix
library(Matrix)
r1 <- sparseMatrix(i = match(df[[1]], row.names(rmatrix)),
j = match(df[[2]], colnames(rmatrix)), x = rmatrix[as.matrix(df)])
r1
# 4 x 4 sparse Matrix of class "dgCMatrix"
#[1,] . 8 . 10
#[2,] . . . .
#[3,] . . 59 .
#[4,] 67 25 100 .
If we need to get the NA values
(NA^!r1)*r1
#4 x 4 Matrix of class "dgeMatrix"
# [,1] [,2] [,3] [,4]
#[1,] NA 8 NA 10
#[2,] NA NA NA NA
#[3,] NA NA 59 NA
#[4,] 67 25 100 NA
This can be converted to a normal matrix by wrapping with as.matrix
Upvotes: 2