【问题标题】:How to aggregate the ranked data?如何聚合排名数据?
【发布时间】:2020-03-11 13:37:44
【问题描述】:

我有一个数据集,显示了前 10 本书的相对价格变化 ((p2 - p1) / p1),如下所示:

df <- tribble(
~book_id,  ~p1, ~p2,  ~change_in_p,
  1,         3,   5,     0.667,
  2,         4,   6,     0.5,
  3,         8,   9,     0.125,
  4,         1,   1,     0,
  5,         3,   4,     0.333, 
  6,         8,   8,     0,
  7,         3,   5,     0.667,
  8,         4,   6,     0.5,
  9,         8,   9,     0.125, 
 10,         1,   1,     0,
)

现在我想将价格变化汇总为 4 个互斥组:

1. No change
2. <50% increase
3. 50 - 69.99% increase
4. >=70% increase

并根据前 2、前 5、前 7 和前 10 的书籍。

例如,前 2 名中价格上涨 0% 的图书的百分比为 0%。两者 (100%) 的价格都上涨了 51 - 70%。

对于前 5 名,20% (1/5) 没有变化,40% 增加了

这是所需的数据:

desired_df <- tribble(
  ~top,      ~no_change, ~betw_0.0001_5_perc_change, ~betw_5_7_perc_change,  ~more_7_per_change,
 'top2',        "0%",              "0%",                 '100%',                '0%',
 'top5',       "20%",             "40%",                 '40%',                 '0%',
 'top7',      "28.6%",          "28.6%",                '42.9%',                 '0%',
 'top10',      "30%",             "30%",                  '40%',                 '0%',
)

到目前为止我做了什么?

由于无法对top 2、top5、top7、top10等书籍进行分组,所以我基本上都看了所有数据:

labels = c('less_5_perc_change', 'betw_5_7_perc_change',  'more_7_per_change')

df%>% 
  group_by(cols = cut(change_in_p, breaks = c(-Inf, 0.49, 0.69, Inf), labels = labels)) %>% 
  summarise(n = n_distinct(book_id)) %>% 
  mutate(pct = scales::percent(n/sum(n), 1)) %>% 
  pivot_wider(id_cols = cols, names_from = cols, values_from = pct) 

很遗憾,我无法获得所需的数据。

【问题讨论】:

  • 你能显示你已经尝试过的代码吗?
  • 谁关闭了这个?!
  • 我真的不明白为什么它被关闭了。如果有什么不清楚的地方,他们基本上可以问不清楚的地方在哪里。 @爱德华
  • 我很清楚。我也正要发布答案。叹息。
  • 但是最后两行的百分比是错误的(我认为)。所有行的总和应为 100%。

标签: r dplyr tidyverse


【解决方案1】:

使用 dplyr,我创建了top 变量,汇总百分比变化,计算累积和,然后转换为百分比。

library(dplyr)

pct <- function(x, top) paste0(round(cumsum(x)*100/top,1),"%")

df %>%
  mutate(top = ifelse(book_id<=2, 2, 
                      ifelse(book_id<=5,5,
                             ifelse(book_id<=7,7,10)))) %>% 
  group_by(top) %>%
  summarise(no_change = sum(change_in_p==0),
            betw_0_50_perc_change=sum(change_in_p>0 & change_in_p<0.5),
            betw_51_70_perc_change=sum(change_in_p>=0.5 & change_in_p<0.7),
            more_70_perc_change=sum(change_in_p>=0.7)) %>%
  mutate_at(vars(-top), ~pct(., top))  # convert to % for all vars except top

# A tibble: 4 x 5
    top no_change betw_0_50_perc_change betw_51_70_perc_change more_70_perc_change
  <dbl> <chr>     <chr>                 <chr>                  <chr>              
1     2 0%        0%                    100%                   0%                 
2     5 20%       40%                   40%                    0%                 
3     7 28.6%     28.6%                 42.9%                  0%                 
4    10 30%       30%                   40%                    0% 

【讨论】:

    【解决方案2】:

    基于 R 的一个想法可以是循环 2、5、7、10,这将表示每个行的数量,然后使用 cut 找到间隔并简单地使用 prop.table 函数来计算频率,即

    x<- c(2, 5, 7, 10)
    labels1 = c('no_change' ,'less_5_perc_change', 'betw_5_7_perc_change', 'more_7_per_change')
    
    d2 <- do.call(rbind, 
       lapply(x, function(i) { i1 <- df[seq(i),]; 
             i2 <- cut(i1$change_in_p, breaks = c(-Inf, 0, 0.49, 0.69, Inf), labels = labels1);
             paste0(round(prop.table(table(i2))*100, 1), '%')}))
    

    给出,

         [,1]    [,2]    [,3]    [,4]
    [1,] "0%"    "0%"    "100%"  "0%"
    [2,] "20%"   "40%"   "40%"   "0%"
    [3,] "28.6%" "28.6%" "42.9%" "0%"
    [4,] "30%"   "30%"   "40%"   "0%"
    

    把它整理成你想要的格式,然后

    setNames(data.frame(cbind(paste0('top', x)), d2), c('top', labels1))
    

    最终给出,

        top no_change less_5_perc_change betw_5_7_perc_change more_7_per_change
    1  top2        0%                 0%                 100%                0%
    2  top5       20%                40%                  40%                0%
    3  top7     28.6%              28.6%                42.9%                0%
    4 top10       30%                30%                  40%                0%
    

    【讨论】:

      猜你喜欢
      • 2023-01-17
      • 1970-01-01
      • 1970-01-01
      • 2011-01-16
      • 2015-07-27
      • 1970-01-01
      • 1970-01-01
      • 2017-01-24
      • 2023-03-08
      相关资源
      最近更新 更多