这是我的交易数据:
id from_id to_id amount date_trx
<fctr> <fctr> <fctr> <dbl> <date>
0 7468 5695 700.0 2005-01-04
1 6213 9379 11832.0 2005-01-08
2 7517 8170 1000.0 2005-01-10
3 6143 9845 4276.0 2005-01-12
4 6254 9640 200.0 2005-01-14
5 6669 5815 200.0 2005-01-20
6 6934 8583 49752.0 2005-01-24
7 9240 8314 19961.0 2005-01-26
8 6374 8865 1000.0 2005-01-30
9 6143 6530 13.4 2005-01-31
...
我操纵它如下:
data %>% group_by(date_trx=floor_date(date_trx, "week"),from_id) %>%
summarize(amount=sum(amount)) %>%
filter(amount > 1000)
在这里,我所做的是,我想每周对数据进行排序,这样我就可以看到每个账户每周的交易总额,然后得到只高于某个值的数据,在我的情况下是1000。
我得到了以下信息:
date_trx from_id amount
<date> <fctr> <dbl>
2005-01-02 5773 7174.0
2005-01-02 6213 12032.0
2005-01-02 6375 3742.0
2005-01-02 6510 5698.0
2005-01-02 6727 5923.0
2005-01-02 7047 1100.0
2005-01-02 7207 1100.0
2005-01-02 9440 1100.0
2005-01-02 9493 4201.0
2005-01-09 5997 5209.0
...
现在,我想得到满足上述过滤条件的原始数据。我该怎么做?为了更清楚地说明,让我们考虑5773。我们知道2005年01月02日5773笔交易的总金额是7174.0,所以这个金额高于1000的阈值,所以我保留了这个账户。但在以这种方式过滤后,我只想提取总金额为7174.0的单个交易。
我们不需要summarise
,只需要filter
分组后删除创建的临时列。注意,tidyverse
中的许多函数可以在不创建列的情况下进行动态计算(sum(amount)
(
library(dplyr)
library(lubridate)
data %>%
group_by(date_trx_week =floor_date(date_trx, "week"),from_id) %>%
filter(sum(amount) > 1000) %>%
ungroup %>%
select(-date_trx_week)
这里有一个方法。
-
添加
week_trx
作为日期的floor
,而不是替换date_trx
。在汇总之前也要这样做,因为我们将使用它将数据连接回汇总中。 -
重命名为
sum_amount
,这样我们就可以很容易地用总和来区分原始/单个amount
。(当然,没有这个步骤,我们可以很容易地区分它们,但你会有amount.x
和amount.y
的名字,这对我来说不太直观。(
dat <- mutate(dat, week_trx = lubridate::floor_date(date_trx, "week"))
datsumm <- dat %>%
group_by(week_trx, from_id) %>%
summarize(sum_amount = sum(amount)) %>%
filter(sum_amount > 1000) %>%
ungroup()
datsumm
# # A tibble: 4 x 3
# week_trx from_id sum_amount
# <date> <int> <dbl>
# 1 2005-01-02 6213 11832
# 2 2005-01-09 6143 4276
# 3 2005-01-23 6934 49752
# 4 2005-01-23 9240 19961
left_join(datsumm, dat, by = c("week_trx", "from_id"))
# # A tibble: 4 x 7
# week_trx from_id sum_amount id to_id amount date_trx
# <date> <int> <dbl> <int> <int> <dbl> <date>
# 1 2005-01-02 6213 11832 1 9379 11832 2005-01-08
# 2 2005-01-09 6143 4276 3 9845 4276 2005-01-12
# 3 2005-01-23 6934 49752 6 8583 49752 2005-01-24
# 4 2005-01-23 9240 19961 7 8314 19961 2005-01-26
在本示例中,摘要中有四行,重新联接的表中有四行将出现,但当每个from_id
有一行以上时,您将得到更具代表性的结果。作为演示,我将调整几个from_id
,以便有一些共性。
set.seed(4)
dat2 <- dat %>%
mutate(from_id = sample(head(from_id, 3), size = n(), replace = TRUE))
datsumm2 <- dat2 %>%
group_by(week_trx, from_id) %>%
summarize(sum_amount = sum(amount)) %>%
filter(sum_amount > 1000) %>%
ungroup()
datsumm2
# # A tibble: 3 x 3
# week_trx from_id sum_amount
# <date> <int> <dbl>
# 1 2005-01-02 7468 11832
# 2 2005-01-09 7468 5276
# 3 2005-01-23 7517 69713
left_join(datsumm2, dat2, by = c("week_trx", "from_id"))
# # A tibble: 5 x 7
# week_trx from_id sum_amount id to_id amount date_trx
# <date> <int> <dbl> <int> <int> <dbl> <date>
# 1 2005-01-02 7468 11832 1 9379 11832 2005-01-08
# 2 2005-01-09 7468 5276 2 8170 1000 2005-01-10
# 3 2005-01-09 7468 5276 3 9845 4276 2005-01-12
# 4 2005-01-23 7517 69713 6 8583 49752 2005-01-24
# 5 2005-01-23 7517 69713 7 8314 19961 2005-01-26
数据:
dat <- read.table(header=TRUE, stringsAsFactors=FALSE, text="
id from_id to_id amount date_trx
0 7468 5695 700.0 2005-01-04
1 6213 9379 11832.0 2005-01-08
2 7517 8170 1000.0 2005-01-10
3 6143 9845 4276.0 2005-01-12
4 6254 9640 200.0 2005-01-14
5 6669 5815 200.0 2005-01-20
6 6934 8583 49752.0 2005-01-24
7 9240 8314 19961.0 2005-01-26
8 6374 8865 1000.0 2005-01-30
9 6143 6530 13.4 2005-01-31")
dat$date_trx <- as.Date(dat$date_trx)