【问题标题】:Find mean for sorted top n transactions查找排序前 n 个事务的均值
【发布时间】:2025-12-23 05:00:17
【问题描述】:

让我的数据框有 2 列,customer id & transaction amount。现在对于每个唯一的客户 ID,我想找到交易金额(按降序排序)然后从排序的列中我将找到排序列表中前三笔交易的平均交易金额。

Cust_id     trans_amount
12345          100      
12345          200      
12345          170      
12345          300      
12345          250
12456          140        
12456          240       
12456          160       
12456          100          

我正在寻找的格式是,

Cust_id     trans_amount
12345          300               
12345          250      
12345          200      
12345          170      
12345          100
12456          240        
12456          160       
12456          140       
12456          100          

然后是前 3 名的平均值,即,

Cust_id    mean_for_top_3
12345         250
12456         180

中间部分,我试过了,

ddply(cust_data,.(cust_id.),summarize,sorted_amount=sort(trans_amount,,decreasing=TRUE))

但没有得到结果。请告知我如何达到我想要的输出。

【问题讨论】:

    标签: r


    【解决方案1】:

    使用data.table的解决方案:

    library(data.table)
    setDT(cust_data)
    cust_data_sort <- cust_data[, .(trans_amount = sort(trans_amount, decreasing = TRUE)), Cust_id]
    cust_data_sort[, .(mean_for_top_3 = mean(head(trans_amount, 3))), Cust_id]
       Cust_id mean_for_top_3
    1:   12345            250
    2:   12456            180
    

    如果你不需要排序表cust_data_sort,那么你可以使用这个来获取平均值:

    cust_data[, .(mean_for_top_3 = mean(head(sort(trans_amount, decreasing = TRUE), 3))), Cust_id]
    

    【讨论】:

    • 是的,它确实有效,我赞成你的回答。如果我必须找到两列的唯一组合的方法,我该如何修改你的代码?我的意思是,如果我的数据有一个“月”列,并且我将尝试找到每个唯一客户 ID 和月份的前 3 次交易的平均值,我应该将“月”列放在此代码中的哪个位置?
    • @HindolGanguly 你应该用, .(month, Cost_Id] 替换, Cost_Id],它应该可以工作。如果它有助于解决您的问题,您可以接受我的回答。
    【解决方案2】:

    使用dplyr 的惯用解决方案

    df <- read.table(text = "Cust_id     trans_amount
    12345          100      
                     12345          200      
                     12345          170      
                     12345          300      
                     12345          250
                     12456          140        
                     12456          240       
                     12456          160       
                     12456          100    ", header  = T)
    
    
    library(dplyr)
    
    df %>% group_by(Cust_id) %>% 
      arrange(desc(trans_amount), .by_group = T) %>%
      top_n(n = 3) %>%
      summarize(mean = mean(trans_amount))
    
    # A tibble: 2 x 2
      Cust_id  mean
        <int> <dbl>
    1   12345   250
    2   12456   180
    

    与计数的替代:

      > df %>% group_by(Cust_id) %>% 
    +   #arrange(desc(trans_amount), .by_group = T) %>% 
    +   mutate(count = n()) %>%
    +   top_n(n = 3, wt = trans_amount) %>%
    +   mutate(mean = mean(trans_amount)) %>%
    +   select(Cust_id,mean,count) %>% distinct()
    # A tibble: 2 x 3
    # Groups:   Cust_id [2]
      Cust_id  mean count
        <int> <dbl> <int>
    1   12345   250     5
    2   12456   180     4
    > 
    

    【讨论】:

    • 如果上面的代码和mean一起修改,我还需要找到交易的数量吗?我的意思是输出将是,Cust_id mean_top_3 trans_count 12345 250 5 12456 180 4
    • 不,计数将与原始数据中的一样,就像 12345 为 5 和 12456 为 4 一样
    • 尽管Error in arrange_impl(.data, dots) : incorrect size (1), expecting : 50000 50000 是我的数据长度,但您的代码引发错误
    • 错误是当前代码还是添加计数的时候?
    • 您是否在引号中给出了 trans_amount?