Mark
Mark

Reputation: 1769

Find the number of times that each row of a matrix appears in another

We have two matrices, which we denote by A and B respectively. The aim is to find the number of times that each row of A appears in B, memorizing these numbers in a vector x whose i-th element corresponds to the i-th row of A. For example:

# A=
1 2 3
1 1 1
2 0 1
1 4 5

# B=
2 0 1
0 0 1
0 0 2

Then the vector x is:

0 0 1 0

because the rows

1 2 3, 1 1 1, 1 4 5

appear 0 times in B, while the row

2 0 1

appears 1 time in B.

The following is my solution:

m3 <- rbind(A, B)
count(m3)

which returns:

  x.1 x.2 x.3 freq
1   0   0   1    1
2   1   0   2    1
3   1   1   1    1
4   1   2   3    1
5   1   4   5    1
6   2   0   1    2

This is not the desidered result. The correct one takes into account the original order of A (while the order of remaining row of B does not matter); in our example:

1   1   2   3    1
2   1   1   1    1
3   2   0   1    2
4   1   4   5    1
1   0   0   1    1
2   1   0   2    1

Upvotes: 0

Views: 73

Answers (2)

ssp3nc3r
ssp3nc3r

Reputation: 3822

Here's a short version:

x <- vector()
for(i in 1:nrow(A)) x[i] = sum(colSums(!t(B) - A[i,] == 0) == 0)

Or you can make it cleaner subbing apply for the for loop. Answer,

> x
[1] 0 0 1 0

Here's the apply version:

x <- sapply(1:nrow(A), function(x) sum(colSums(!t(B) - A[x,] == 0) == 0) )

I'm sure it can be simplified further.

Upvotes: 1

www
www

Reputation: 39154

A solution using dplyr. m_final is the final output.

library(dplyr)
dt <- rbind(A, B) %>%
  as_data_frame() 

dt_unique <- dt %>%
  distinct()

dt_count <- dt %>%
  group_by_all() %>%
  count()

m_final <- dt_unique %>%
  left_join(dt_count) %>%
  as.matrix()

m_final
#      V1 V2 V3 n
# [1,]  1  2  3 1
# [2,]  1  1  1 1
# [3,]  2  0  1 2
# [4,]  1  4  5 1
# [5,]  0  0  1 1
# [6,]  0  0  2 1

DATA

A <- matrix(c(1, 2, 3,
              1, 1, 1,
              2, 0, 1,
              1, 4, 5), ncol = 3, byrow = TRUE)

B <- matrix(c(2, 0, 1,
              0, 0, 1,
              0, 0, 2), ncol = 3, byrow = TRUE) 

Upvotes: 1

Related Questions