【问题标题】:Group variables by values with % of each other按彼此的百分比对变量进行分组
【发布时间】:2021-07-17 14:16:04
【问题描述】:

我想对具有特定列的 df 行进行分组,该列的值彼此为 x%。 例如,在 df 中,10% 的值差异将分为 3 组:(A、C、F)、(B、D)、(E)。 所以某种分组方式的值有 +/- 10% 的变化。

tibble(Item = c("A","B","C","D","E","F"), value = c(1.01,2.42,1.03,2.45, 3.1, 0.99))

【问题讨论】:

  • 如果 3 个这样的值是 1、1.09、1.18,百分比仅为 10%
  • 在我使用这个的情况下,这种情况是不可能的,所以不用担心这个。
  • 好的。看答案。这适用于(i)您想将它们组合在一起或(ii)这种情况不会发生的情况。

标签: r data.table tidyverse data-manipulation


【解决方案1】:

作为一个快速而肮脏的解决方案,我建议:

library(tidyverse)

df <- tibble(Item = c("A","B","C","D","E","F"), value = c(1.01,2.42,1.03,2.45, 3.1, 0.99))

df %>%
  mutate(group = ceiling((value/max(value))/0.1))

您可以在其中更改 0.1 除数。

【讨论】:

    【解决方案2】:

    这样的事情会奏效。那么“组”就是Item。

    您可以看到,由于您指定的方式,会出现许多边缘情况。您可以删除参数 mult = "first" 来解析它们。

    dt <- data.table(tibble(Item = c("A","B","C","D","E","F"), value = c(1.01,2.42,1.03,2.45, 3.1, 0.99)))
    dt[, `:=`(lower_bound = value * .9,
              upper_bound = value * 1.1)]
    dt[dt, on = .(value > lower_bound,
                  value < upper_bound), mult = "first"][, .(i.Item), Item]
    
    #    Item i.Item
    # 1:    A      A
    # 2:    A      C
    # 3:    A      F
    # 4:    B      B
    # 5:    B      D
    # 6:    E      E
    
    

    【讨论】:

      【解决方案3】:

      由于您已在 cmets 中阐明顺序元素不会相互冲突,因此您可以这样做

      library(dplyr)
      df %>% arrange(value) %>% 
        group_by(grp = cumsum(lag(value, default = 0)*1.1 <= value)) %>%
        ungroup() %>%
        arrange(Item)
      
      # A tibble: 6 x 3
        Item  value   grp
        <chr> <dbl> <int>
      1 A      1.01     1
      2 B      2.42     2
      3 C      1.03     1
      4 D      2.45     2
      5 E      3.1      3
      6 F      0.99     1
      

      如果value 中可能存在负值,这也会产生预期结果

      df %>% arrange(value) %>% 
        group_by(grp = 1 + cumsum(lag(value, default = first(value))*1.1 <= value)) %>%
        ungroup() %>%
        arrange(Item)
      
      # A tibble: 6 x 3
        Item  value   grp
        <chr> <dbl> <dbl>
      1 A      1.01     1
      2 B      2.42     2
      3 C      1.03     1
      4 D      2.45     2
      5 E      3.1      3
      6 F      0.99     1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-06
        • 2019-05-15
        • 1970-01-01
        • 2013-10-08
        • 2021-06-07
        相关资源
        最近更新 更多