如何同时使用spread、group_by、summarise和mutate?

6

我希望您能根据'年份'这一列将以下数据(仅显示前12行)进行“展开”,返回按'国家名称'分组的'订单'总和。然后计算每个'国家名称'在2014年至2015年之间'订单'数量的百分比变化。

CountryName     Days        pCountry     Revenue    Orders  Year
United Kingdom  0-1 days    India        2604.799   13      2014
Norway          8-14 days   Australia    5631.123   9       2015
US              31-45 days  UAE          970.8324   2       2014
United Kingdom  4-7 days    Austria      94.3814    1       2015
Norway          8-14 days   Slovenia     939.8392   3       2014
South Korea     46-60 days  Germany      1959.4199  15      2014
UK              8-14 days   Poland       1394.9096  6.      2015
UK              61-90 days  Lithuania   -170.8035   -1      2015
US              8-14 days   Belize       1687.68    5       2014
Australia       46-60 days  Chile        888.72 2.  0       2014
US              15-30 days  Turkey       2320.7355  8       2014
Australia       0-1 days    Hong Kong    672.1099   2       2015

我可以用一个较小的测试数据框来使这个代码工作,但是在使用完整数据时却只能返回无尽的错误,例如“因素无意义的总和”或“行标识符重复”。经过几个小时的阅读dplyr文档并尝试各种方法后,我已经放弃了。有人能帮忙解决这段代码吗...

data %>% 
  spread(Year, Orders) %>% 
  group_by(CountryName) %>%
  summarise_all(.funs=c(Sum='sum'), na.rm=TRUE) %>% 
  mutate(percent_inc=100*((`2014_Sum`-`2015_Sum`)/`2014_Sum`))

预期的输出结果应该类似于以下表格。(注:这些数字仅用于说明目的,它们不是手动计算的。)
CountryName  percent_inc
UK           34.2
US           28.2
Norway       36.1
...          ...

编辑

我不得不对变量名进行一些修改,请注意。


3
请使用 dput 提供样本数据和期望结果。 - HubertL
2个回答

5

在数据仍处于长格式时先进行汇总,然后再展开。以下是一个使用虚假数据的示例:

set.seed(2)
dat = data.frame(Country=sample(LETTERS[1:5], 500, replace=TRUE), 
                 Year = sample(2014:2015, 500, replace=TRUE),
                 Orders = sample(-1:20, 500, replace=TRUE))

dat %>% group_by(Country, Year) %>% 
  summarise(sum_orders = sum(Orders, na.rm=TRUE)) %>% 
  spread(Year, sum_orders) %>%
  mutate(Pct = (`2014` - `2015`)/`2014` * 100)
  Country `2014` `2015`        Pct
1       A    575    599  -4.173913
2       B    457    486  -6.345733
3       C    481    319  33.679834
4       D    423    481 -13.711584
5       E    528    551  -4.356061

如果你有多年的数据,最好保持长格式,直到你准备制作漂亮的输出表格为止:

set.seed(2)
dat = data.frame(Country=sample(LETTERS[1:5], 500, replace=TRUE), 
                 Year = sample(2010:2015, 500, replace=TRUE),
                 Orders = sample(-1:20, 500, replace=TRUE))

dat %>% group_by(Country, Year) %>% 
  summarise(sum_orders = sum(Orders, na.rm=TRUE)) %>% 
  group_by(Country) %>%
  arrange(Country, Year) %>%
  mutate(Pct = c(NA, -diff(sum_orders))/lag(sum_orders) * 100) 
   Country  Year sum_orders        Pct
    <fctr> <int>      <int>      <dbl>
 1       A  2010        205         NA
 2       A  2011        144  29.756098
 3       A  2012        226 -56.944444
 4       A  2013        119  47.345133
 5       A  2014        177 -48.739496
 6       A  2015        303 -71.186441
 7       B  2010        146         NA
 8       B  2011        159  -8.904110
 9       B  2012        152   4.402516
10       B  2013        180 -18.421053
# ... with 20 more rows

无法形容我对此的感激之情 - 完美地运行 :) - RDJ

2
这不是一个答案,因为您并没有真正提出一个可重复的问题,但我会协助您。 错误1:您遇到了错误duplicate identifiers for rows,很可能是由于spread引起的。 spread想要将您的N个唯一值创建为N列,但它需要知道将哪些唯一行放置这些值。如果您有重复的值组合,例如:
   CountryName      Days        pCountry         Revenue
United Kingdom  0-1 days           India        2604.799
United Kingdom  0-1 days           India        2604.799

该数据出现了两次,因此spread会困惑应该将数据放在哪一行中。快速解决方法是在spread之前执行data %>% mutate(row=row_number()) %>% spread...

错误2:您收到错误消息sum not meaningful for factors可能是由于summarise_all引起的。summarise_all将对所有列操作,但某些列包含字符串(或因子)。 United Kingdom + United Kingdom等于什么?请改为使用summarise(2014_Sum = sum(2014), 2015_Sum = sum(2015))


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接