代码之家  ›  专栏  ›  技术社区  ›  byouness

有没有一个函数是to near()在%中的%是to==?

  •  2
  • byouness  · 技术社区  · 7 年前

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

    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 回复  |  直到 7 年前
        1
  •  2
  •   moodymudskipper    7 年前

    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
    

    或者在tidyverse语言中也使用 purrr 包裹:

    data %>%
      filter(reduce(map(c(0.5679, 5.6789), near, x= x, tol = 1e-4),`|`))
    
        2
  •  2
  •   Konrad Rudolph    7 年前

    near(x, y) 已经矢量化,因此将其包装 any 生成单个值。

    在你的情况下使用它,你只需要 map x 值:

    data %>% filter(map_lgl(x, ~ any(near(.x, c(0.5679, 5.6789), tol = 1e-4))))
    
        3
  •  1
  •   Lennyy    7 年前
    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.
    
        4
  •  0
  •   Wimpel    7 年前

    您可以使用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
    
    推荐文章