根据每列的有效值列表计算每行的无效值 (R) 更新

问题描述

我正在寻找一种快速计算每行无效值的方法。这里以一个数据框为例:

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

我想要一个额外的数字列,它可以显示每种情况下有多少值与列表中定义的有效值不对应。例如,此列表可能如下所示:

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

所以我在这个例子中寻找的列是:

data$invalid <- c(1,0)

我更喜欢 tidyverse 解决方案。我尝试了一些不同的 purrr::map 函数,但不幸的是找不到任何可行的解决方案。提前感谢您提供任何有用的提示

解决方法

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))))