Подсчитайте количество нулей в каждой строке большого data.frame с помощью функции purrr :: map

У меня очень большой фрейм данных 280000 x 20, и во многих строках (obs) есть только значения 1 или 0. Функция, которую я использую, требует как минимум 2 значений на операцию. Я могу выполнять итерацию с помощью цикла for, но это занимает много времени. Я хотел бы использовать одну из функций карты purrr для увеличения скорости, поскольку я буду делать это много раз. Вот как я делал это с циклом for:

library(Matrix)
M1 <- as.matrix(rsparsematrix(100, 20, .1, rand.x = runif))
x <- vector("integer")
for(i in 1:dim(M1)[1]){
  l <- (length(which(M1[i,] == 0)))
  x <- c(x,l)
}
ind <- which(x == 19 | x == 20)
M1 <- M1[-ind,]

Я не понял, как это сделать с помощью карты. Я предполагаю, что для этого потребуется создать еще один столбец с помощью mutate.

M1 %>% mutate(zero_count = length(map(which(. == 0))))

person dhbrand    schedule 13.04.2018    source источник


Ответы (2)


Не совсем ясно об ожидаемом. Сначала мы преобразуем matrix в tibble или data.frame, затем mutate столбцы в логические столбцы, reduce в один vector, добавляя (+) все ИСТИННЫЕ значения в каждой строке и cbind с vector с исходной матрицей ('M1')

library(tidyverse)
M1 %>% 
  as_tibble %>%
  mutate_all(funs(.==0)) %>%
  reduce(`+`) %>% 
  cbind(M1, Count = .)

Обновлять

Для подмножества строк на основе суммы

M1 %>% 
  as_tibble %>% 
  mutate_all(funs(.==0)) %>% 
  reduce(`+`) %>% 
  `%in%`(19:20)  %>%
  magrittr::extract(M1, .,)

С base R это rowSums на логическом matrix и cbind с исходным matrix

cbind(M1, Count = rowSums(!M1))

Или подмножество с rowSums

M1[rowSums(!M1) %in% 19:20, ]
person akrun    schedule 13.04.2018
comment
Это было именно то, что мне было нужно. Новый столбец во фрейме данных может фильтровать любые строки, где счетчик равен 19 или 20, что означает, что в наблюдении есть только 1 или 0 значений. - person dhbrand; 13.04.2018

Вы можете добиться того же с apply

apply(M1, 1 , function(x) sum(!x))
person Relasta    schedule 13.04.2018
comment
Мне удалось успешно запустить цикл for, но в моем наборе данных почти 300 тысяч наблюдений. Для его запуска с использованием цикла for потребовалось 4 минуты и 1 секунда для его запуска с использованием метода purrr, предоставленного @akrun. Я пытался использовать аккуратные пакеты для единообразия над семейством функций apply. Вы правы, подайте заявку - это хороший вариант. - person dhbrand; 13.04.2018