【问题标题】:Summarize without reducing rows在不减少行的情况下进行汇总
【发布时间】:2015-02-22 11:29:27
【问题描述】:

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

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

所以,我只需要在 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 汇总(第 3 步)处失败,因为代码无法在第二次汇总后保留“产品”列,即使它在 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')) 

【问题讨论】:

  • 为什么要以高度不可读的嵌套方式编写,而不是使用管道?
  • @Khashaa:真的不是这里的问题。如果可以的话,请帮忙。我以 %>% 格式发布相同的代码: KPS Rollup data_df %>% group_by(Key, Subc, Prod) %>% select (Key, Subc, Prod, Cash) %>% summarise(Cash_KSP = sum(Cash, na.rm = TRUE)) 等

标签: r dplyr


【解决方案1】:

与其使用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

【讨论】:

  • 在这个过程之后我可以安排()和变异(排名())吗?我正在尝试这样做: data % mutate(Rank_K=rank(-data$Cash_K, ties. method = 'first')) 但即使排序有效,我也会将所有 Rank_K 都设为 1。我尝试通过安排()进行排序,但这也不会影响数据。
  • @KavindraM。不要在 dplyr 函数中使用 data$ ......它会否定所有分组,因为您从数据框的外部副本强制输入整个列。只需使用不带引号的列名,%&gt;% 提供数据参数。
  • 哇!每天都有新东西。谢谢。那不是我很聪明。
  • 我只是浪费了一整天对着我的笔记本电脑尖叫。 :P
  • @KavindraM。我添加了一个带有排列的示例
猜你喜欢
  • 2017-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
  • 1970-01-01
  • 2013-05-15
  • 2015-04-28
  • 1970-01-01
相关资源
最近更新 更多