在不减少行的情况下进行汇总

Summarize without reducing rows

我有一个数据集,我基本上需要汇总和自我合并。

有一段旧代码使用了非常低效(缓慢)的 SQLDF。所以,我输入了 dplyr summarise(),这是我一生中见过的最快的汇总,这比 SAS 好。

我的数据集 (data_df) 有 3 个标识列 (KeyProdSubc) 和一个数值字段 (Cash)需要在 3 列的各种独特组合中进行总结。由于这是一个大型数据集,为了将我的 RAM 使用率降至最低,我尝试对所有 3 个级别的组合进行汇总,并将汇总的数据保存在同一数据集中。

Key Prod Subc Cash
K1  P1   S1   10
K2  P2   S3   30
K1  P1   S2   10
K3  P4   S4   40

现在,我想添加 3 个新的汇总列(Cash_K、Cash_KP、Cash_KS、Cash_KSP)数据集。

Key Prod Subc Cash Cash_K Cash_KP Cash_KS Cash_KSP
K1  P1   S1   10   20     20      10      10 
K2  P2   S3   30   30     30      30      30
K1  P1   S2   10   20     20      10      10
K3  P4   S4   40   40     40      40      40

我现在使用的代码生成了 4 个数据集:

KPS Rollup  
data_df_1 <- summarise(select(group_by(data_df,Key, Subc, Prod), Cash), Cash_KSP = sum(Cash, na.rm = TRUE))

rm(data_df)

KS Rollup
data_df_2 <- summarise(select(group_by(data_df,Key, Subc), Cash_KSP), Cash_KS = sum(Cash_KSP, na.rm = TRUE))

K Rollup
data_df_3 <- summarise(select(group_by(data_df,Keyword), Cash_KS), Cash_K = sum(Cash_KS, na.rm = TRUE))

KP Rollup
data_df_4 <- summarise(select(group_by(data_df,Keyword,Product),Cash_KSP), Cash_KP = sum(Cash_KSP, na.rm = T))

对于喜欢 %>% 符号的人:

KPS Rollup 
data_df %>% group_by(Key, Subc, Prod) %>% summarise(Cash_KSP = sum(Cash, na.rm = TRUE)) %>% select (Key, Subc, Prod, Cash_KSP) etc.

因此,我只需要 "proper" 在 KSP 级别汇总。其他汇总基本上是在每个唯一组合处重复汇总。

我写了类似这样的东西:

KPS Rollup  
data_1 <- summarise(select(group_by(data_df,Key, Subc, Prod), Cash), Cash_KSP = sum(Cash, na.rm = TRUE))

rm(data)

KS Rollup
data_2 <- summarise(select(group_by(data_1,Key, Subc),Prod, Cash_KSP), Cash_KS = sum(Cash_KSP, na.rm = TRUE))

K Rollup
data_2 <- summarise(select(group_by(data_2,Key),Subc,Prod, Cash_KS), Cash_K = sum(Cash_KS, na.rm = TRUE))

KP Rollup
data_2 <- summarise(select(group_by(data_2,Key,Prod),Subc, Cash_KSP), Cash_KP = sum(Cash_KSP, na.rm = T))

但是代码在 K Rollup(第 3 步)失败,因为代码无法在第二次汇总后保留 'Prod' 列,即使在 select 语句中提到了它。

dplyr 或任何其他方法可以不需要任何合并吗?使用 dplyr 时是否有任何保留?

编辑:

所有四个新列的排名,我该怎么做? Mutate(rank(), dense_rank()) 似乎不起作用。没有排序发生,所有行的排名 = 1,任何 group_by 组合也不会更正它。

data <- data[order(-data$Cash_K),] 
data <- group_by(data, Key, Subc, Prod) %>% mutate(Rank_K=rank(-data$Cash_K, ties.method = 'first')) 

与其使用summarise,不如使用mutate

data_df <- read.table(text="Key Prod Subc Cash
K1  P1   S1   10
K2  P2   S3   30
K1  P1   S2   10
K3  P4   S4   40", header=TRUE)

library(dplyr)

data_df <- data_df %>% group_by(Key) %>% mutate(Cash_K=sum(Cash)) %>%
  group_by(Key,Prod) %>% mutate(Cash_KP=sum(Cash)) %>%
  group_by(Key,Subc) %>% mutate(Cash_KS=sum(Cash)) %>%
  group_by(Key,Subc,Prod) %>% mutate(Cash_KSP=sum(Cash))

结果如下 data_df

> data_df

  Key Prod Subc Cash Cash_K Cash_KP Cash_KS Cash_KSP
1  K1   P1   S1   10     20      20      10       10
2  K2   P2   S3   30     30      30      30       30
3  K1   P1   S2   10     20      20      10       10
4  K3   P4   S4   40     40      40      40       40

当您只需要 Cash_KSP 变量时:

data_df <- data_df %>% group_by(Key,Subc,Prod) %>% mutate(Cash_KSP=sum(Cash))

您可以安排您的数据框,例如:

data_df <- data_df %>% arrange(Key)

这导致:

> data_df

  Key Prod Subc Cash Cash_K Cash_KP Cash_KS Cash_KSP
1  K1   P1   S1   10     20      20      10       10
2  K1   P1   S2   10     20      20      10       10
3  K2   P2   S3   30     30      30      30       30
4  K3   P4   S4   40     40      40      40       40