这是我的交易数据:
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。
答案 0 :(得分:1)
这是一种方法。
添加week_trx
作为日期的floor
,而不是替换date_trx
。在汇总之前也要这样做,因为我们将使用它来将数据重新合并到摘要中。
重命名为sum_amount
,这样我们就可以轻松地将原始amount
与原始{div}相加。 (当然,无需执行此步骤,我们就可以轻松区分它们,但是您会使用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)
答案 1 :(得分:1)
我们不需要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)