R:如何根据多个条件求和并汇总table
R: How to sum based on multiple criteria and summarize table
这是我的原始数据框:
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[= 中的每个日期都有一个唯一的记录39=],同时在新列 中为日期列 中的值之前的所有日期提供 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 条记录,每个日期有数百个不同的索引字段。
我以前在使用 by
和 aggregate
炸毁我的硬盘之前就这样做过,但是这个过程非常缓慢,我无法解决这个问题周围的时间。我也尝试过 ddply
,但无法使用 cumsum
函数。使用 ddply
,我尝试了类似的方法:
ddply(xo1, .(Date,Index), summarise,
sum.x = sum(Event == 'x'),
sum.y = sum(Event == 'y'))
无济于事。
通过搜索,我找到了 Replicating an Excel SUMIFS formula
这让我得到了我项目的累积部分,但是有了这个我无法弄清楚如何将它总结为每个 date/index 组合只有一条记录。我也遇到了 sum/aggregate data based on dates, R 但在这里我无法计算出动态日期方面。
感谢任何可以提供帮助的人!
像这样使用 dplyr
和 tidyr
行得通吗?
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
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 步:定义忽略 NA
的 cumsum()
函数
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)
)
这是我的原始数据框:
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[= 中的每个日期都有一个唯一的记录39=],同时在新列 中为日期列 中的值之前的所有日期提供 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 条记录,每个日期有数百个不同的索引字段。
我以前在使用 by
和 aggregate
炸毁我的硬盘之前就这样做过,但是这个过程非常缓慢,我无法解决这个问题周围的时间。我也尝试过 ddply
,但无法使用 cumsum
函数。使用 ddply
,我尝试了类似的方法:
ddply(xo1, .(Date,Index), summarise,
sum.x = sum(Event == 'x'),
sum.y = sum(Event == 'y'))
无济于事。
通过搜索,我找到了 Replicating an Excel SUMIFS formula
这让我得到了我项目的累积部分,但是有了这个我无法弄清楚如何将它总结为每个 date/index 组合只有一条记录。我也遇到了 sum/aggregate data based on dates, R 但在这里我无法计算出动态日期方面。
感谢任何可以提供帮助的人!
像这样使用 dplyr
和 tidyr
行得通吗?
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
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 步:定义忽略 NA
cumsum()
函数
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)
)