检查值是否在多个列中排除某个值(标签)的范围内

时间:2018-04-24 08:54:11

标签: r range apply

我在下面的表格中有一个数据集:

structure(list(ID = 1:10, Text1 = c(5L, 8L, 3L, 1L, 3L, 67L, 
800L, 5L, 9L, 2L), Text2 = c(800L, 800L, 2L, NA, 14L, 3L, 70L, 
6L, 9L, 1L), Text3 = c(3L, 88L, 800L, NA, 4L, NA, 7L, 5L, 7L, 
800L), Text4 = c(1L, 6L, 12L, 1L, 6L, 800L, 1L, NA, 8L, 2L)), .Names = c("ID", 
"Text1", "Text2", "Text3", "Text4"), class = "data.frame", row.names = c(NA, 
-10L))


> data
   ID Text1 Text2 Text3 Text4
1   1     5   800     3     1
2   2     8   800    88     6
3   3     3     2   800    12
4   4     1    NA    NA     1
5   5     3    14     4     6
6   6    67     3    NA   800
7   7   800    70     7     1
8   8     5     6     5    NA
9   9     9     9     7     8
10 10     2     1   800     2

我想检查每个Text列中的值。可接受的值范围是110重要提示:范围还应接受范围内的所有十进制数,例如2.3,3.5等)。但也有一个800数字,这是一个特殊的标签也被接受

OUTPUT :我希望ID的单元格不满足上述条件。

对于超大型数据集(约500万行)执行此操作的最快方法是什么?

我尝试使用withsapply执行此操作,但我没有成功:

with(data, (Text1 <= 10 & Text1 >= 1) | Text1 == 800)

这适用于一列。但我无法理解如何获取ID并将相同的函数应用于每一列。

apply(data, grep(pattern = "Text", names(data)), 
    function(x){with(x, (x <= 10 & x >= 1) | x == 800)})

这也行不通。

2 个答案:

答案 0 :(得分:0)

如果我们需要检查每个列,遍历感兴趣的列(lapply,),使用比较运算符来获取逻辑向量

lst <- lapply(data[-1], function(x) (x >= 0 & x <= 10 & !is.na(x)) | x %in% 800)

目前尚不清楚预期产量。如果我们要删除没有

范围内的值的行
data[Reduce(`&`, lst),, drop = FALSE]

或仅获取&#39; ID&#39>

data$ID[Reduce(`&`, lst)]

或使用tidyverse

library(dplyr)
library(purrr)
data %>%
   mutate_at(vars(-ID), funs((. >= 1 & . <= 10 & !is.na(.)) | . %in% 800)) %>%
   reduce(`&`) %>%
   filter(data, .)

答案 1 :(得分:0)

也许:

check_fun <- function(x) {
  x <- as.numeric(x)
  which(!(x <= 10 & x >= 1) | !(x == 800) == FALSE)
}
res <- lapply(data[ , paste0("Text", 1:4)], check_fun) # like akrun, this could be a result
unlist(lapply(seq_along(res), function(x) paste(res[[x]], x + 1, sep = ","))) 
# or with indices, <row,column>