8

I'm very surprised this question has not been asked, maybe the answer will clear up why. I want to compare rows of a matrix to a vector and return whether the row == the vector everywhere. See the example below. I want a vectorized solution, no apply functions because the matrix is too large for slow looping. Suppose there are many rows as well, so I would like to avoid repping the vector.

set.seed(1)

M = matrix(rpois(50,5),5,10)

v = c(3 ,   2 ,   7  ,  7 ,   4   , 4   , 7  ,  4  ,  5, 6)

M
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]    4    8    3    5    9    4    5    6    7     7
[2,]    4    9    3    6    3    1    5    7    6     1
[3,]    5    6    6   11    6    4    5    2    7     5
[4,]    8    6    4    4    3    8    3    6    5     6
[5,]    3    2    7    7    4    4    7    4    5     6

Output should be

FALSE  FALSE FALSE FALSE TRUE
Frank
  • 66,179
  • 8
  • 96
  • 180
wolfsatthedoor
  • 7,163
  • 18
  • 46
  • 90

3 Answers3

10

One possibility is

rowSums(M == v[col(M)]) == ncol(M)
## [1] FALSE FALSE FALSE FALSE  TRUE

Or simlarly

rowSums(M == rep(v, each = nrow(M))) == ncol(M)
## [1] FALSE FALSE FALSE FALSE  TRUE

Or

colSums(t(M) == v) == ncol(M)
## [1] FALSE FALSE FALSE FALSE  TRUE

v[col(M)] is just a shorter version of rep(v, each = nrow(M)) which creates a vector the same size as M (matrix is just a vector, try c(M)) and then compares each element against its corresponding one using ==. Fortunately == is a generic function which has an array method (see methods("Ops") and is.array(M)) which allows us to run rowSums (or colSums) on it in order to makes sure we have the amount of matches as ncol(M)

David Arenburg
  • 91,361
  • 17
  • 137
  • 196
5

Using DeMorgan's rule (Not all = Some not), then All equal = Not Some Not equal, we also have

!colSums(t(M) != v)
Neal Fultz
  • 9,282
  • 1
  • 39
  • 60
0

The package prodlim has a function called row.match, which is easy to use and ideal for your problem. First install and load the library: library(prodlim). In our example, row.match will return '5' because the 5th row in M is equal to v. We can then convert this into a logical vector.

m <- row.match(v, M)
m==1:NROW(M)#[1] FALSE FALSE FALSE FALSE  TRUE
milan
  • 4,782
  • 2
  • 21
  • 39