如何根据某些字段在 R 中进行 cumsum?

How to cumsum in R based on certain fields?

对于篇幅,我深表歉意,但这是必要的,以免跳过细节并使它比现在更加混乱。

下面是示例数据和我到目前为止所做的一些操作。

library(dplyr)
library(tidyverse)

emp <- c(1,2,3,4,5,6,7,8,1,12,54,101,33,159,201,261,110,195,131,228)
small <- c(1,1,1,1,1,1,1,1,1,1,1,2,1,3,3,4,2,3,2,3)
area <-c(003,003,003,003,003,003,003,003,003,003,003,003,003,003,003,003,003,003,003,003)
twodigit <-c(11,22,11,22,23,22,11,31,44,45,21,44,45,62,72,22,45,72,45,21)

smbtest2 <- data.frame(emp,small,area,twodigit)

所以在我走得太远之前,我的目标是将就业 (emp) 按小数(下面的模式)求和,然后按两位数(行业代码)将其分解。在这个简单的例子中,我想要每个小类别的前 3 个行业。我正在尝试 cumsum,因为如果一个在第一类(0 到 99)中,那么它将在第二类(0 到 149)中。

smbsummary3<-smbtest2 %>% 
group_by(area,small,twodigit) %>%
summarise(emp = sum(emp), worksites = n(), 
        .groups = 'drop_last')%>%
slice_max(emp,n=3)

smbsummary4<-smbsummary3 %>% 
ungroup %>% 
complete(area, small = unique(small)) %>% 
fill(emp, worksites)

 Schema for small
 1     0 to 99
 2     0 to 149
 3     0 to 249
 4     0 to 499

期望的结果

   area     small   twodigit    emp    worksites
   003        1        21        54        1
   003        1        45        45        2       (12+33)
   003        1        22        12        3       (2+4+6)
   003        2        45       286        4       (12+33+110+131)
   003        2        44       102        2       (1+101)
   003        2        21        54        1

目前纯粹是根据small来求和,这是根据代码应该做的。但是,我的问题是如何根据小类得出cumsum(累计和)?

以下是我最近的尝试。它加起来不是正确答案,但我认为它接近于正确的命令集。

smbsummary3<-smbtest2 %>% 
group_by(area,small,twodigit) %>%
summarise(emp = sum(emp), worksites = n(), 
        .groups = 'drop_last')%>%
mutate(emp = cumsum(emp),
     worksites = cumsum(worksites))%>%
slice_max(emp,n=3)

我本来打算在评论中解释,但这似乎更容易。

也许您想要 group_by 只是 areatwodigit,然后再进行累计。

然后,group_by 再次 select 前 3 个 empareasmall。结果输出看起来非常相似(在数据集中找不到 small 2 和 twodigit 21)。

smbtest2 %>%
  group_by(area, small, twodigit) %>%
  summarise(emp = sum(emp), 
            worksites = n(), 
            .groups = 'drop_last') %>%
  group_by(area, twodigit) %>%
  mutate(emp = cumsum(emp),
         worksites = cumsum(worksites)) %>%
  group_by(area, small) %>%
  slice_max(emp, n = 3) %>%
  arrange(area, small, desc(emp))

输出

   area small twodigit   emp worksites
  <dbl> <dbl>    <dbl> <dbl>     <int>
1     3     1       21    54         1
2     3     1       45    45         2
3     3     1       22    12         3
4     3     2       45   286         4
5     3     2       44   102         2
6     3     3       72   396         2
7     3     3       21   282         2
8     3     3       62   159         1
9     3     4       22   273         4