Подсчет недопустимых значений в строке на основе списка допустимых значений в столбце (R)

Я ищу быстрый метод для подсчета недопустимых значений в строке. Вот кадр данных в качестве примера:

data <- data.frame("c1" = c(1,1,3,0,2,2,3,1,2,9),
                   "c2" = c(2,2,3,4,1,2,1,2,1,2),
                   "c3" = c(2,3,3,4,3,3,3,3,2,9),
                   "c4" = c(4,4,0,0,1,0,3,0,3,9),
                   "c5" = c(9,1,2,3,2,1,2,3,2,1))

Я хотел бы иметь дополнительный числовой столбец, который показывает мне в каждом случае, сколько значений не соответствует допустимым значениям, определенным в списке. Например, этот список может выглядеть так:

valid <- list("c1" = c(1:4,9),
              "c2" = c(1:3,9),
              "c3" = c(2:4,9),
              "c4" = c(0:3,9),
              "c5" = c(1:3,9))

Таким образом, столбец, который я ищу в этом примере, будет:

data$invalid <- c(1,1,0,2,0,0,0,0,0,0)

Я бы предпочел аккуратное решение. Я немного пробовал разные функции purrr::map, но, к сожалению, не смог найти никакого работающего решения. Заранее благодарю за любые полезные советы.


person MaVe    schedule 20.01.2021    source источник


Ответы (1)


В base R мы можем использовать Map

data$invalid <- unlist(Map(function(x, y) 
          sum(!x %in% y), data, valid[names(data)]))

Или с purrr

library(purrr)
library(dplyr)
imap_int(data, ~  sum(!.x %in% valid[[.y]])) %>%
    mutate(data, invalid = .)

Обновлять

На основе обновленного поста

data$invalid <- Reduce(`+`, lapply(names(valid), 
  function(nm) Reduce(`&`, lapply(valid[[nm]], function(x) data[[nm]] != x))))
person akrun    schedule 20.01.2021
comment
Спасибо за очень быстрый ответ akrun. К сожалению, после применения этого решения к гораздо большему фрейму данных сегодня утром (думаю, для вас уже поздняя ночь), я понял, что оно работает только в том случае, если количество строк и столбцов одинаково. Мой фактический df имеет десять тысяч строк и несколько десятков столбцов (идентично количеству объектов в списке). Следовательно, я изменил пример фрейма данных. - person MaVe; 21.01.2021
comment
@MaVe Пожалуйста, проверьте мое обновление - person akrun; 22.01.2021