是否有一个函数Near()%in%是==?

时间:2018-07-10 08:43:32

标签: r dplyr

我有一个带有数字列x的data.frame或tibble:

library(dplyr)
data <- tibble(x = c(0.123456, 0.5678910, 1.234567, 5.67891011, 12.345678),
               y = c(1, 2, 3, 4, 5))

为了对x与一组值(例如,给定公差,例如1e-4)接近的行进行过滤。 c(0.5679, 5.6789)。我会用这样的东西:

data %>% filter(near(x, 0.5679, 1e-4) | near(x, 5.6789, 1e-4))
#> # A tibble: 2 x 2
#>       x     y
#>   <dbl> <dbl>
#> 1 0.568     2
#> 2 5.68      4

如果我不是c(0.5679, 5.6789)的向量是100个元素,这将变得很冗长...因此,是否有一个函数可以按照以下内容写东西:

data %>% filter(near_any(x, c(0.5679, 5.6789), tol = 1e-4))

换句话说,是否有一个函数near()%in%就是==

(我可以编写这样的near_any()函数,但是在我要检查是否还不存在之前)

由reprex软件包(v0.2.0)于2018-07-10创建。

4 个答案:

答案 0 :(得分:2)

dplyr中它不存在,在基数R中最可能不存在。如果您要询问其他软件包,则不在SO的范围内。

但是您可以这样:

data %>%
  filter(Reduce(`|`,lapply(c(0.5679, 5.6789), near, x= x, tol = 1e-4)))

# # A tibble: 2 x 2
#          x     y
#      <dbl> <dbl>
# 1 0.567891     2
# 2 5.678910     4

或者使用purrr软件包使用tidyverse语言:

data %>%
  filter(reduce(map(c(0.5679, 5.6789), near, x= x, tol = 1e-4),`|`))

答案 1 :(得分:2)

near(x, y)已经向量化,因此将其包装在any中会产生一个单一值。

要在您的情况下使用它,只需在map值上x

data %>% filter(map_lgl(x, ~ any(near(.x, c(0.5679, 5.6789), tol = 1e-4))))

答案 2 :(得分:1)

library(purrr)
library(dplyr)

map_df(c(0.5679,5.6789), function(i) data %>% 
          filter(near(x, i, 1e-4)))


      x     y
  <dbl> <dbl>
1 0.568    2.
2 5.68     4.

答案 3 :(得分:0)

您可以使用data.tables(非常快)foverlaps()

library(data.table)
#create the data.table
data <- data.table( x = c(0.123456, 0.5678910, 1.234567, 5.67891011, 12.345678),
                    y = c(1, 2, 3, 4, 5))
#add a min-max column to join  on. they are both eequal to the value of x
data[, c("min", "max") := list(x, x)]

#set the precision
precision <- 1e-4

#create a data.table with filter values and theur range (+/- precision)
filter_values <- setDT(data.table( x = c(0.5679, 5.6789)))
filter_values[, c("min", "max") := list(x - precision, x + precision)]
#set key for join
setkey(filter_values, min, max)

#perform an overlap-join, keep only columns x and y, where a match with a filter_value is found
foverlaps(data,filter_values)[!is.na(x),c("x","y")]

#         x y
# 1: 0.5679 2
# 2: 5.6789 4