【问题标题】:Select rows by ID with most matches按 ID 选择匹配最多的行
【发布时间】:2018-08-21 18:35:32
【问题描述】:

我有一个这样的数据框:

df <- data.frame(id = c(1,1,1,2,2,3,3,3,3,4,4,4),
                 torre = c("a","a","b","d","a","q","t","q","g","a","b","c"))

并且我希望我的代码为每个id 选择重复更多的torre,或者为id 选择最后一个torre,如果没有一个比另一个重复更多,所以我会得到一个像这样的新数据框:

df2 <- data.frame(id = c(1,2,3,4), torre = c("a","a","q","c"))

【问题讨论】:

    标签: r dataframe aggregate


    【解决方案1】:

    你可以使用aggregate:

    aggregate(torre ~ id, data=df,
      FUN=function(x) names(tail(sort(table(factor(x, levels=unique(x)))),1))
    )
    

    这个函数的完整解释有点复杂,但大部分工作都是由FUN= 参数完成的。在这种情况下,我们正在创建一个函数,获取每个 torre 的频率计数,按升序对它们进行排序,然后使用 tail(, 1) 获取最后一个并取其名称。 aggregate() 函数然后为每个 id 单独应用此函数。

    【讨论】:

      【解决方案2】:

      您可以使用dplyr 包执行此操作:按idtorre 分组以计算每个torre/id 组合的出现次数,然后仅按id 分组并选择组内频率最高的 torre 最后出现。

      library(dplyr)
      df %>% 
      group_by(id,torre) %>% 
      mutate(n=n()) %>% 
      group_by(id) %>% 
      filter(n==max(n)) %>%
      slice(n()) %>% 
      select(-n)
           id torre
        <dbl> <chr>
      1     1     a
      2     2     a
      3     3     q
      4     4     c
      

      【讨论】:

        【解决方案3】:

        包的方法:

        library(data.table)
        setDT(df)[, .N, by = .(id, torre)][order(N), .(torre = torre[.N]), by = id]
        

        给出:

           id torre
        1:  1     a
        2:  2     a
        3:  3     q
        4:  4     c
        

        还有两个可能的 替代方案:

        library(dplyr)
        
        # option 1
        df %>% 
          group_by(id, torre) %>% 
          mutate(n = n()) %>% 
          group_by(id) %>% 
          mutate(f = rank(n, ties.method = "first")) %>% 
          filter(f == max(f)) %>% 
          select(-n, -f)
        
        # option 2
        df %>% 
          group_by(id, torre) %>% 
          mutate(n = n()) %>% 
          distinct() %>% 
          arrange(n) %>% 
          group_by(id) %>% 
          slice(n()) %>% 
          select(-n)
        

        【讨论】:

          【解决方案4】:

          又一个dplyr 解决方案,这次使用add_count() 而不是mutate()

          df %>%
            add_count(id, torre) %>% 
            group_by(id) %>% 
            filter(n == max(n)) %>% 
            slice(n()) %>% 
            select(-n)
          
          # A tibble: 4 x 2
          # Groups:   id [4]
               id torre
            <dbl> <fct>
          1    1. a    
          2    2. a    
          3    3. q    
          4    4. c   
          

          【讨论】:

            猜你喜欢
            • 2013-12-26
            • 1970-01-01
            • 2016-06-01
            • 2012-10-09
            • 1970-01-01
            • 2013-06-25
            • 2014-07-13
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多