首页 文章

汇总Dataframe中的最低值?

提问于
浏览
0

我的数据框如下所示:

View(df)
Product     Value
  a           2
  b           4 
  c           3
  d           10
  e           15
  f           5
  g           6
  h           4
  i           50
  j           20
  k           35
  l           25
  m           4
  n           6
  o           30
  p           4
  q           40
  r           5
  s           3
  t           40

我想找到9种最昂贵的产品,并总结其余的产品 . 它应该如下所示:

Product     Value 
  d           10
  e           15
  i           50
  j           20
  k           35
  l           25
  o           30
  q           40
  t           40
 rest         46

休息是其他11种产品的总和 . 我用 summaries 尝试了它,但它不起作用:

new <- df %>%
  group_by(Product)%>%
summarise((Value > 10) = sum(Value)) %>%
  ungroup()

3 回答

  • 1

    我们可以使用 dplyr::row_number 在使用 arrangeValue 对数据进行排序后对观测值进行有效排名 . 然后,我们扩充 Product 列,以便不在前9中的任何值编码为 Rest . 最后,我们按更新的 Product 进行分组,并使用 summarise 获取总和

    dat %>%
        arrange(desc(Value)) %>%
        mutate(RowNum = row_number(),
               Product = ifelse(RowNum <= 9, Product, 'Rest')) %>%
        group_by(Product) %>%
        summarise(Value = sum(Value))
    
    # A tibble: 10 × 2
       Product Value
         <chr> <int>
    1        d    10
    2        e    15
    3        i    50
    4        j    20
    5        k    35
    6        l    25
    7        o    30
    8        q    40
    9     Rest    46
    10       t    40
    

    数据

    dat <- structure(list(Product = c("a", "b", "c", "d", "e", "f", "g", 
    "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t"
    ), Value = c(2L, 4L, 3L, 10L, 15L, 5L, 6L, 4L, 50L, 20L, 35L, 
    25L, 4L, 6L, 30L, 4L, 40L, 5L, 3L, 40L)), .Names = c("Product", 
    "Value"), class = "data.frame", row.names = c(NA, -20L))
    
  • 1

    使用 dplyr 的另一种方法是使用 do 创建结果 . 代码变得有点难以阅读,因为你需要使用 .$ ,但你可以避免使用 ifelse/if_else . 在按 Value 排列订单后,您可以创建两个向量 . 一个有前九个产品名称和"rest" . 另一个具有前九个值和其他值的总和 . 您可以使用 do 直接创建数据框 .

    df %>%
    arrange(desc(Value)) %>%
    do(data.frame(Product = c(as.character(.$Product[1:9]), "Rest"),
                  Value = c(.$Value[1:9], sum(.$Value[10:length(.$Value)]))))
    
    #   Product Value
    #1        i    50
    #2        q    40
    #3        t    40
    #4        k    35
    #5        o    30
    #6        l    25
    #7        j    20
    #8        e    15
    #9        d    10
    #10    Rest    46
    
  • 2

    这是使用 data.table 的一个选项

    library(data.table)
    setDT(df)[, i1 := .I][order(desc(Value))
              ][-(seq_len(9)), Product := 'rest'
               ][, .(Value = sum(Value), i1=i1[1L]), Product
               ][order(Product=='rest', i1)][, i1 := NULL][]
    #    Product Value
    #1:       d    10
    #2:       e    15
    #3:       i    50
    #4:       j    20
    #5:       k    35
    #6:       l    25
    #7:       o    30
    #8:       q    40
    #9:       t    40
    #10:   rest    46
    

相关问题