计算分组变量和另一个变量的总和之间的差异

时间:2021-07-02 15:10:44

标签: r dataframe dplyr data-wrangling

我有一个这样的数据框:

example.df <- data.frame(Year = rep(1:3, each = 3),
                         Product = rep(c("bottle_water", "tap_water", "juice"), 3),
                         Product_grouped = rep(c("water", "water", "juice"), 3),
                         Required = c(10, 15, 10, 10, 20, 10, 10, 35, 0),
                         Group_avail = rep(c(25, 25, 10), 3),
                         Purchased = c(0, 0, 0, 5, 0, 0, 20, 0, 0))
> example.df
  Year      Product Product_grouped Required Group_avail Purchased
1    1 bottle_water           water       10          25         0
2    1    tap_water           water       15          25         0
3    1        juice           juice       10          10         0
4    2 bottle_water           water       10          25         5
5    2    tap_water           water       20          25         0
6    2        juice           juice       10          10         0
7    3 bottle_water           water       10          25        20
8    3    tap_water           water       35          25         0
9    3        juice           juice        0          10         0

对于每个 Year,我有每个 RequiredProduct 数量。其中两个产品(tap_waterbottled_water)可以归入water。在这种情况下,可用的总数量显示在 Group_avail 中。

在总 Required Product_grouped 大于 Group_avail 的年份,我想购买差额。但是,差异必须仅在 Purchased 中为 bottle_water。例如,在 Year 2 中,我们需要 20 tap_water 和 10 bottle_water,但只有 25 水可用,因此 5 bottle_waterPurchased。< /p>

我正在寻找适合管道的解决方案。

谢谢!

编辑 我添加了另一个 Year 以进一步明确我想要什么。在超过 Required 的总 Product_grouped 的任何情况下,应始终以 bottle_water 购买差额。

2 个答案:

答案 0 :(得分:3)

有点不雅,但是这使用管道通过拆分瓶水然后添加回数据帧来实现结果。

temp <- example.df

temp <- temp %>% 
  group_by(Product_grouped, Year) %>% 
  filter(Product %in% c("bottle_water", "tap_water")) %>% 
  mutate(Required_grouped = sum(Required)) %>% 
  filter(Product == "bottle_water") %>% 
  mutate(Purchased = ifelse(Required_grouped - Group_avail > 0, Required_grouped - Group_avail, 0)) %>% 
  select(-"Required_grouped")
  
example.df <- example.df %>% 
  filter(Product != "bottle_water") %>% 
  bind_rows(temp) %>% 
  arrange(Year)

如果订单很重要,则将 Product 设置为一个因子并添加到 arrange(Year)

答案 1 :(得分:3)

我希望这就是你要找的。为了您的目的,我首先修改了 Required 列以显示每个 sumProduct_grouped,然后我检查每个组的第一行中的总和是否超过 Group_avail。万一我们计算了差异,前提是我们的第一个类别始终是 bottle_water。如果您想将 Required 列恢复为其原始形式,我可以进行修改,以确保这是您首先要查找的内容。

library(dplyr)

example.df %>%
  group_by(Year, Product_grouped) %>%
  mutate(Required = sum(Required),
         Purchased02 = if_else(Required >= Group_avail & Product == "bottle_water", 
                               Required - Group_avail, 0))

# A tibble: 9 x 7
# Groups:   Year, Product_grouped [6]
   Year Product      Product_grouped Required Group_avail Purchased Purchased02
  <int> <chr>        <chr>              <dbl>       <dbl>     <dbl>       <dbl>
1     1 bottle_water water                 25          25         0           0
2     1 tap_water    water                 25          25         0           0
3     1 juice        juice                 10          10         0           0
4     2 bottle_water water                 30          25         5           5
5     2 tap_water    water                 30          25         0           0
6     2 juice        juice                 10          10         0           0
7     3 bottle_water water                 45          25        20          20
8     3 tap_water    water                 45          25         0           0
9     3 juice        juice                  0          10         0           0
相关问题