R — Подсчитать количество «истинных» значений в столбцах матрицы и присвоить «False»

#r #matrix

#r #матрица

Вопрос:

У меня есть матрица, которая выглядит примерно так:

 set.seed(1234)
m <- matrix(round(runif(50,0,4)), ncol=10)
m <- (m>2)
  
       [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9] [,10]
[1,] FALSE  TRUE  TRUE  TRUE FALSE  TRUE FALSE  TRUE FALSE FALSE
[2,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE
[3,] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE
[4,] FALSE  TRUE  TRUE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE
[5,]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE
  

Для каждого столбца мне нужно подсчитать количество TRUE s. Если общее количество TRUE символов в столбце меньше 3,
затем мне нужно, чтобы каждый TRUE из этого столбца стал FALSE .

Для этого примера ожидаемый результат будет:

       [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9] [,10]
[1,] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE
[2,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[3,] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE
[4,] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE
[5,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE
  

Моя реальная матрица намного больше (100 000 x 2000), поэтому решение должно быть быстрым.

Есть какие-либо подсказки о том, как туда добраться?

Ответ №1:

Во-первых, определение количества столбцов может быть выполнено с помощью `colSums:

 colSums(m)
#  [1] 1 2 2 1 0 3 0 3 1 2
  

Затем, точно так же, как вы перезаписываете m матрицу своим m <- m > 2 , вы можете перезаписать столбцы выбора условным:

 m[, colSums(m) < 3] <- FALSE
m
#       [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9] [,10]
# [1,] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE
# [2,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# [3,] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE
# [4,] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE
# [5,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE
  

Ответ №2:

Мы также можем использовать apply

 m[, apply(m, 2, sum) < 3] <- FALSE
  

Или используя tidyverse

 library(dplyr)
m %>% 
   as.data.frame %>% 
   mutate(across(everything(), ~ replace(., sum(.) < 3, FALSE)))