总结而不减少行

时间:2015-02-22 11:29:27

标签: r dplyr

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

有一个使用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

现在使用的代码I生成了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))

对于喜欢%&gt;%表示法的人:

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

所以,我需要&#34;正确的&#34;仅在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步)失败,因为代码无法保持&#39; Prod&#39;第二次汇总后的列,即使在select语句中提到它。

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

编辑:

所有四个新列的排名,我该怎么做? Mutate(rank(),dense_rank())似乎不起作用。不进行排序,所有行都得到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')) 

1 个答案:

答案 0 :(得分:3)

最好不要使用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