Majority vote in matrix in R

Asked

Viewed 63 times

3

I want to compare elements of a matrix, for example, in row 1 (fixed) I want to know which object happens with the most frequency and return the same, precise in an automated way, because the number of columns is variable.

Follow an example of the code:

M = 3
a = matrix(sample(1:2, 300, replace = T), ncol = M)
combinado = rep(0, nrow(a))

i = 1
while(i <= nrow(a)){
  if(sum(a[i,]) == 3||sum(a[i,]) == 4) combinado[i] = 1
  else combinado[i] = 2
  i = i + 1
}

Where I would like to vary the M, respecting the dimension of the clear matrix.

2 answers

3


You can do this easily using a combination of apply with table:

count <- apply(a, 1, function(r) as.numeric(names(which.max(table(r)))))

We have to use as.numeric because names returns a string result.

Demonstrating the result:

> identical(combinado, count)
[1] TRUE

2

As you want to know the value of higher frequency on each line, I would suggest making one lapply of function table per line and then check the highest frequency value:

sapply(lapply(split(a, row(a)), table), function(x) names(which.max(x)))
  [1] "2" "1" "2" "2" "2" "1" "1" "1" "1" "1" "1" "1" "2" "2" "1" "1" "1" "1" "2" "1" "2"
 [22] "1" "1" "2" "1" "1" "2" "1" "1" "1" "2" "1" "2" "2" "2" "2" "1" "1" "1" "2" "2" "1"
 [43] "2" "2" "1" "2" "2" "1" "2" "1" "1" "1" "1" "2" "1" "2" "1" "2" "1" "2" "1" "2" "2"
 [64] "1" "2" "1" "2" "1" "2" "1" "2" "2" "2" "2" "2" "1" "1" "2" "2" "1" "2" "2" "1" "2"
 [85] "1" "2" "1" "2" "2" "1" "1" "1" "1" "2" "1" "2" "1" "1" "1" "2"

Demonstrating that the results are equal to your:

all.equal(combinado, as.numeric(sapply(lapply(split(a, row(a)), table), function(x) names(which.max(x)))))
[1] TRUE

Note that with the apply now the calculation does not depend on the number of columns of the matrix. Making with M = 5:

M = 5
a = matrix(sample(1:2, 300, replace = T), ncol = M)
sapply(lapply(split(a, row(a)), table), function(x) names(which.max(x)))
 [1] "2" "2" "1" "2" "2" "2" "2" "2" "2" "1" "2" "1" "2" "2" "2" "2" "1" "2" "2" "1" "2"
[22] "1" "1" "2" "1" "2" "1" "1" "1" "2" "1" "2" "2" "2" "1" "1" "1" "2" "2" "2" "1" "2"
[43] "2" "2" "2" "2" "1" "1" "2" "1" "2" "2" "1" "2" "2" "1" "2" "2" "2" "2"
  • Carlos, in your solution if we increase the size from M to 11, for example, it creates an empty list.

  • 1

    @Wagnerjorge perfect Wagner, it really happens because apply tries to simplify the result for an array. I hadn’t thought of this situation. To prevent this from happening it is enough to use the lapply on the lines instead of the apply, I changed the answer.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.