【问题标题】:conditional matching between variables in dplyrdplyr中变量之间的条件匹配
【发布时间】:2020-12-09 11:49:58
【问题描述】:

我试图在另一列中找到具有某些或所有可能值的列中的观察值。在这个小标题里

parties <- tibble(class = c("R","R","R","R","R","K","K","K","K","K","K",
                "L","L","L","L"),
       name = c("Party1", "Party2","Party3","Party4","Party5",
               "Party2", "Party4", "Party6","Party7","Party8","Party9",
                "Party2","Party3","Party4","Party10"))

我想找到属于“R”、“K”和“L”三个类别的所有“派对”。或者通常属于“X”或“Y”类的各方。我设法找到了一个解决方案,使用group_split(class),然后从列表中提取每个表,最后执行两个半连接。这适用于我想要所有三个classes 的聚会的情况:

parties_split <- parties %>%
  group_split(class)

parties_K <- parties_split[[1]]
parties_L <- parties_split[[2]]
parties_R <- parties_split[[3]]

semi_join(parties_K,parties_L, by = "name") %>%
  semi_join(parties_R, by = "name") %>%
  select(-class)

name
<chr>
Party2              
Party4

这在这种情况下可行,但效率不高,尤其是当需要匹配的类(或观察)的数量远大于三个时。我特别在 tidyverse 中寻找解决方案。有任何想法吗?谢谢

【问题讨论】:

    标签: r dplyr tibble


    【解决方案1】:

    试试看:

    parties %>% 
      group_by(name) %>% 
      filter("K" %in% class, 
             "R" %in% class, 
             "L" %in% class) %>% 
      summarise()
    
    # A tibble: 2 x 1
      name  
      <chr> 
    1 Party2
    2 Party4
    

    编辑:如果您想与超过 3 方合作,您也可以使用:

    mask = c("K", "R", "L")
    parties %>% 
      group_by(name) %>% 
      filter(all(mask %in% class)) %>% 
      summarise()
    

    【讨论】:

      【解决方案2】:

      要使这项工作适用于许多组,您可以使用purrr::reduce:

      library(dplyr)
      
      parties %>%
        group_split(class) %>%
        purrr::reduce(semi_join, by = "name") %>%
        select(name)
      
      #   name  
      #  <chr> 
      #1 Party2
      #2 Party4
      

      【讨论】:

        【解决方案3】:

        这行得通吗:

        library(dplyr)
        parties %>% group_by(name) %>% mutate(cnt = n()) %>% 
           group_by(class) %>% mutate(grpno = group_indices()) %>% ungroup() %>% 
            filter(cnt >= max(grpno)) %>% select(name) %>% distinct()
        # A tibble: 2 x 1
          name  
          <chr> 
        1 Party2
        2 Party4
        

        【讨论】:

        • 是的!我不得不对我的真实数据集进行一些调整,因为有重复等。但它有效,谢谢!
        【解决方案4】:

        另一种解决方案

        library(tidyverse)
        
        parties %>% 
          group_by(class) %>% 
          distinct() %>% 
          mutate(id = 1) %>%  
          pivot_wider(name, names_from = class, values_from = id) %>% 
          rowwise() %>% 
          filter(!is.na(sum(c_across(where(is.numeric))))) %>% 
          select(name) %>% 
          ungroup()
        #> # A tibble: 2 x 1
        #>   name  
        #>   <chr> 
        #> 1 Party2
        #> 2 Party4
        

        由reprex package (v0.3.0) 于 2020-12-09 创建

        【讨论】:

          猜你喜欢
          • 2020-06-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-04-20
          • 1970-01-01
          • 2019-12-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多