首页 > 解决方案 > 按 r 中的总收入计算每个月的收入

问题描述

假设一家咨询公司每月发布公司 A 和 B 在区域 alpha 和 beta 的总收入,数据可能如下所示:

# generate data

foo <- expand.grid(month = 1:3, region = c("alpha", "beta"), firm = c("A", "B"), stringsAsFactors = FALSE)
foo <- foo[order(foo$month, foo$region),]
rownames(foo) <- 1:nrow(foo)
foo <- foo[c(-1,-6),]
revenue <- c(1.5, 2, 2.1, 1.2, 3, 5.5, 3.2, 5, 5, 6)
foo <- cbind(foo, revenue)
foo

##    month region firm revenue
## 2      1  alpha    B     1.5
## 3      1   beta    A     2.0
## 4      1   beta    B     2.1
## 5      2  alpha    A     1.2
## 7      2   beta    A     3.0
## 8      2   beta    B     5.5
## 9      3  alpha    A     3.2
## 10     3  alpha    B     5.0
## 11     3   beta    A     5.0
## 12     3   beta    B     6.0

我想做的是计算每个月的收入。但我无法处理所有这些情况:</p>

  1. 一月份,这个月的收入是总收入;
  2. 对于新分支,它第一次出现的月份对其他分支来说就像一月;
  3. 而且有些数据会丢失,下个月的收入应该是NA。

基本上,结果是:

result <- c(1.5, 2, 2.1, 1.2, 1, 3.4, 2, NA, 2, 0.5)
res <- cbind(foo, result)
res

##    month region firm revenue result
## 2      1  alpha    B     1.5    1.5
## 3      1   beta    A     2.0    2.0
## 4      1   beta    B     2.1    2.1
## 5      2  alpha    A     1.2    1.2  ## a new branch launched by A at alpha in Feb.
## 7      2   beta    A     3.0    1.0
## 8      2   beta    B     5.5    3.4
## 9      3  alpha    A     3.2    2.0
## 10     3  alpha    B     5.0     NA  ## the data of B at alpha in Feb. is missing
## 11     3   beta    A     5.0    2.0
## 12     3   beta    B     6.0    0.5

先谢谢了~

标签: r

解决方案


我不完全确定这是您正在寻找的,但也许这会有所帮助。我假设这revenue是每个公司/地区组合的总数/累积。

首先,我会注意到收入的首次出现(新分支,您的规则之一)。

foo <- foo %>%
  group_by(region, firm) %>%
  mutate(first = first(month)) %>%
  ungroup()

然后,将扩展以获取firm/region和填充的组合NA,并重新连接到您的数据框。如果月份是一月 (1) ,您可以按和region设置firm分组。否则,设置为与 last 的差异。resultrevenuerevenue

由于新分支将被视为一月,因此更改resultrevenueif the month is the firstmonth and resultwas NA

foo %>%
  expand(firm, nesting(region, month)) %>%
  left_join(foo) %>%
  group_by(region, firm) %>%
  mutate(result = ifelse(month == 1, revenue, revenue-lag(revenue))) %>%
  mutate(result = ifelse((is.na(result)) & (month == first), revenue, result)) %>%
  drop_na(revenue) %>%
  select(-first) %>%
  arrange(month, region)

# A tibble: 10 x 5
# Groups:   region, firm [4]
   firm  region month revenue result
   <chr> <chr>  <int>   <dbl>  <dbl>
 1 B     alpha      1     1.5    1.5
 2 A     beta       1     2      2  
 3 B     beta       1     2.1    2.1
 4 A     alpha      2     1.2    1.2
 5 A     beta       2     3      1  
 6 B     beta       2     5.5    3.4
 7 A     alpha      3     3.2    2  
 8 B     alpha      3     5     NA  
 9 A     beta       3     5      2  
10 B     beta       3     6      0.5

推荐阅读