简体   繁体   English

根据另一个 tibble 过滤 mutate 中的 tibble?

[英]Filter a tibble in mutate based on another tibble?

I have two tibbles, ranges and sites.我有两个小标题、范围和站点。 The first contains a set of coordinates (region, start, end, plus other character variables) and the other contains a sites (region, site).第一个包含一组坐标(区域、开始、结束以及其他字符变量),另一个包含一个站点(区域、站点)。 I need to get all sites in the second tibble that fall within a given range (row) in the first tibble.我需要获取第二个 tibble 中属于第一个 tibble 中给定范围(行)的所有站点。 Complicating matters, the ranges in the first tibble overlap.使问题复杂化的是,第一个小标题中的范围重叠。

# Range tibble
  region start end var_1 ... var_n
1  A     1     5   
2  A     3     10
3  B     20    100
# Site tibble
  region site 
1  A     4        
2  A     8    
3  B     25

The ~200,000 ranges can be 100,000s long over about a billion sites, so I don't love my idea of a scheme of making a list of all values in the range, unnesting, semi_join'ing, grouping, and summarise(a_list = list(site))'ing.大约 200,000 个范围可以是 100,000 多个,超过大约 10 亿个站点,所以我不喜欢我的想法,即列出该范围内的所有值、取消嵌套、semi_join'ing、分组和汇总(a_list =列表(站点))。

I was hoping for something along the lines of:我希望有以下几点:

range_tibble %>%
  rowwise %>%
  mutate(site_list = site_tibble %>%
                filter(region.site == region.range, site > start, site < end) %>%
      .$site %>% as.list))

to produce a tibble like:产生一个像:

# Final tibble
 region start   end    site_list  var_1 ... var_n    
  <chr>  <dbl> <dbl>   <list>     <chr>     <chr>
  1 A          1     5 <dbl [1]>
  2 A          3    10 <dbl [2]>
  3 B         20   100 <dbl [1]>

I've seen answers using "gets" of an external variable (ie filter(b == get("b")), but how would I get the variable from the current line in the range tibble? Any clever pipes or syntax I'm not thinking of? A totally different approach is great, too, as long as it plays well with big data and can be turned back into a tibble.我已经看到使用外部变量的“gets”(即 filter(b == get("b"))的答案,但是我如何从范围 tibble 中的当前行获取变量?任何聪明的管道或语法我没想到?完全不同的方法也很好,只要它适用于大数据并且可以变回小题大做。

Use left_join() to merge two data frames and summarise() to concatenate the sites contained in the specified range.使用left_join()合并两个数据帧和summarise()来连接包含在指定范围内的站点。

library(dplyr)

range %>%
  left_join(site) %>%
  filter(site >= start & site <= end) %>% 
  group_by(region, start, end) %>%
  summarise(site = list(site))

#   region start   end site     
#   <fct>  <dbl> <dbl> <list>   
# 1 A          1     5 <dbl [1]>
# 2 A          3    10 <dbl [2]>
# 3 B         20   100 <dbl [1]>

Data数据

range <- data.frame(region = c("A", "A", "B"), start = c(1, 3, 20), end = c(5, 10, 100))
site <- data.frame(region = c("A", "A", "B"), site = c(4, 8, 25))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM