【问题标题】:R: How to sum based on multiple criteria and summarize tableR:如何根据多个标准求和并汇总表
【发布时间】:2015-03-27 15:34:35
【问题描述】:

这是我的原始数据框:

df <- read.table(text="
  Date         Index  Event
  2014-03-31   A      x
  2014-03-31   A      x
  2014-03-31   A      y
  2014-04-01   A      y
  2014-04-01   A      x
  2014-04-01   B      x
  2014-04-02   B      x
  2014-04-03   A      x
  2014-09-30   B      x", header = T, stringsAsFactors = F)

date_range <- seq(as.Date(min(df$Date)), as.Date(max(df$Date)), 'days')
indices <- unique(df$Index)
events_table <- unique(df$Event)

我希望我想要的输出总结我的数据框,并为 indices 中的每个索引和 date_range 中的每个日期提供唯一记录,同时提供每个事件的累积值events_table 在新列中在日期列中的值之前的所有日期。有时每个索引或每个日期都没有记录。

这是我想要的输出:

Date        Index  cumsum(Event = x) cumsum(Event = y)
2014-03-31  A      0                 0
2014-03-31  B      0                 0
2014-04-01  A      2                 1
2014-04-01  B      0                 0
2014-04-02  A      3                 2
2014-04-02  B      1                 0
...  
2014-09-29  A      4                 2
2014-09-29  B      2                 0
2014-09-30  A      4                 2
2014-09-30  B      2                 0

仅供参考 - 这是数据框的简化版本。每年有大约 200,000 条记录,每个日期都有数百个不同的索引字段。

在我的硬盘使用byaggregate 炸之前,我曾经这样做过,但是这个过程非常缓慢,这次我无法解决它。我也尝试过ddply,但我无法让cumsum 函数使用它。使用ddply,我尝试了类似:

ddply(xo1, .(Date,Index), summarise, 
      sum.x = sum(Event == 'x'), 
      sum.y = sum(Event == 'y'))

无济于事。
通过搜索,我找到了Replicating an Excel SUMIFS formula 这让我得到了我项目的累积部分,但是我无法弄清楚如何将它总结为每个日期/索引组合只有一条记录。我也遇到了sum/aggregate data based on dates, R,但在这里我无法计算出动态日期方面。

感谢任何可以提供帮助的人!

【问题讨论】:

  • 我对您的预期输出感到困惑。在预期输出的一行中,您希望 cumsum(Event = x)0?即使您原来的df 有两行Date = 2014-03-31Index = AEvent = x
  • 强调“我希望我想要的输出总结我的数据框,并为索引中的每个索引和 date_range 中的每个日期提供唯一记录,同时在新列中提供 events_table 中每个事件的累积值 对于日期列之前的所有日期“......作为背景,我正在尝试使用那天早上我可以获得的信息来构建一个模型。所以在 2014-03-31 早上,我没有可用的数据。一整天都在收集数据,在 2014 年 4 月 1 日,2014 年 3 月 31 日的数据是我可以用来预测 2014 年 4 月 1 日事件的数据
  • 感谢您的澄清。我在初次阅读时错过了这一点。

标签: r plyr dplyr


【解决方案1】:
library(dplyr)
library(tidyr)

df$Date <- as.Date(df$Date)

第 1 步:生成 {Date, Index} 对的完整列表

full_dat <- expand.grid(
  Date = date_range, 
  Index = indices,
  stringsAsFactors = FALSE
  ) %>% 
  arrange(Date, Index) %>%
  tbl_df

第 2 步:定义一个忽略 NAcumsum() 函数

cumsum2 <- function(x){

  x[is.na(x)] <- 0
  cumsum(x)

}

第 3 步:生成每个 {Date, Index} 的总数,加入完整的 {Date, Index} 数据, 并计算滞后累积和。

df %>%
  group_by(Date, Index) %>%
  summarise(
    totx = sum(Event == "x"),
    toty = sum(Event == "y")
    ) %>%
  right_join(full_dat, by = c("Date", "Index")) %>% 
  group_by(Index) %>%
  mutate(
    cumx = lag(cumsum2(totx)),
    cumy = lag(cumsum2(toty))
    ) %>%
  # some clean up.
  select(-starts_with("tot")) %>%
  mutate(
    cumx = ifelse(is.na(cumx), 0, cumx),
    cumy = ifelse(is.na(cumy), 0, cumy)
    )

【讨论】:

  • 太棒了。这 200k 行花费了
【解决方案2】:

这样使用dplyrtidyr 会起作用吗?

library(dplyr)
library(tidyr)

df %>%
  group_by(Date, Index, Event) %>%
  summarise(events = n()) %>%
  group_by(Index, Event) %>%
  mutate(cumsum_events = cumsum(events)) %>%
  select(-events) %>%
  spread(Event, cumsum_events) %>%
  rename(sum.x = x,
         sum.y = y)

#        Date Index sum.x sum.y
#1 2014-03-31     A     2     1
#2 2014-04-01     A     3     2
#3 2014-04-01     B     1    NA
#4 2014-04-02     B     2    NA
#5 2014-04-03     A     4    NA
#6 2014-09-30     B     3    NA

【讨论】:

  • 这对于总结一切很有用,谢谢.... 我的目标是为每个唯一索引(所有索引)和日期(日期在 2014-03-31 和 2014-09 之间)创建一个记录-30) 组合,这样我就可以将其导出到一个单独的文件中,直到该点为止的所有年度数据的每一天。有些日子我们不收集关于索引 A 的信息,所以如果我使用这种方法按 date = '2014-04-02' 进行子集化,我只会看到索引 B 而不是 A 的数据。有什么快速的方法可以得到没有为每个唯一的 Date+Index 键添加额外的无效记录??
  • @maloneypatr - 我认为您的解决方案与 OP 的期望输出不匹配。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 2021-11-23
  • 2022-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多