R:如何同时传播,分组,总结和变异

时间:2017-06-21 22:53:04

标签: r dplyr tidyr

我希望通过“'年”列中的spread以下数据(此处显示的前12行),返回'订单'的总和。按' CountryName'分组。然后计算“订单”中的百分比变化。对于每个' CountryName'从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
...          ...

修改

我必须对变量名进行一些编辑,请注意。

2 个答案:

答案 0 :(得分:3)

首先,当您的数据仍然是长格式时,然后传播。这是假数据的一个例子:

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

答案 1 :(得分:1)

是一个答案,因为你没有真正问过一个可重现的问题,只是为了帮忙。

错误1 由于duplicate identifiers for rows,您可能会收到错误spreadspread想要为N个唯一值设置N列,但需要知道放置这些值的唯一行。如果您有重复的值组合,例如:

   CountryName      Days        pCountry         Revenue
United Kingdom  0-1 days           India        2604.799
United Kingdom  0-1 days           India        2604.799

显示两次,然后spread混淆了它应该将数据放入哪一行。快速解决方法是在data %>% mutate(row=row_number()) %>% spread...之前spread

错误2 由于sum not meaningful for factors,您可能会收到错误summarise_allsummarise_all将对所有列进行操作,但有些列包含字符串(或因子)。 United Kingdom + United Kingdom等于什么?请改为summarise(2014_Sum = sum(2014), 2015_Sum = sum(2015))