【发布时间】:2018-09-05 11:02:38
【问题描述】:
我有每个用户的观察列表;每个用户每天可能对foo 进行多次观察。对于每个不同的日子,我想要foo 值的累积计数。这是我到目前为止得到的:
library(tidyverse)
library(lubridate)
df = tribble(
~user_id, ~foo, ~bar, ~created_at,
1, "a", "b", "2018-07-30",
1, "a", "c", "2018-07-31",
1, "a", "c", "2018-07-31",
1, "b", "a", "2018-08-01",
1, "b", "c", "2018-08-02",
1, "b", "a", "2018-08-03",
1, "a", "a", "2018-08-03",
2, "b", "b", "2018-07-30",
2, "b", "c", "2018-07-31",
2, "a", "a", "2018-08-01",
2, "a", "a", "2018-08-01",
2, "a", "c", "2018-08-02",
2, "a", "c", "2018-08-02",
2, "a", "a", "2018-08-03"
) %>% mutate_at("created_at", as_datetime)
df %>%
mutate(cutoff_date = created_at %>% date) %>%
group_by(user_id, foo, cutoff_date) %>%
tally %>%
mutate(foo_cnt = cumsum(n)) %>%
select(-n) %>%
arrange(user_id, cutoff_date, foo)
这给了我:
user_id foo cutoff_date foo_cnt
<dbl> <chr> <date> <int>
1 1. a 2018-07-30 1
2 1. a 2018-07-31 3
3 1. b 2018-08-01 1
4 1. b 2018-08-02 2
5 1. a 2018-08-03 4
6 1. b 2018-08-03 3
7 2. b 2018-07-30 1
8 2. b 2018-07-31 2
9 2. a 2018-08-01 2
10 2. a 2018-08-02 4
11 2. a 2018-08-03 5
太好了,所以我知道在 8 月 3 日之前,用户 1 已经看到了四次 a 和三次 b。我现在想知道,对于我的数据中出现的每个日期(我不关心丢失的日期):
- 截至日期的特定
foo观察的总数 - 与其他观察相比的相对数量
也就是说,输出应该是:
user_id cutoff_date foo foo_cnt foo_cnt_total foo_pct
1 1. 2018-07-30 a 1 1 100
2 1. 2018-07-30 b 0 0 0
3 1. 2018-07-31 a 3 4 100
4 1. 2018-07-31 b 0 0 0
5 1. 2018-08-01 a 3 7 87.5
6 1. 2018-08-01 b 1 1 12.5
...
在第 5 行中,这一比例为 87.5%,因为在此之前用户已经看到了七次 a 和一次 b。
我知道如何到达那里,但我正在努力为数据中存在的日期包含 foo 的其他值,但没有观察到 foo。我已经查看了complete(),但我不知道如何使用它来填充剩余的值。
例如,当我添加其中任何一个时,我不会得到额外的列:
complete(nesting(user_id, foo), cutoff_date)
complete(user_id, cutoff_date, foo)
我错过了什么?
更新:我按照建议添加了ungroup,现在我也得到了每天的总数。我已经使用fill 为foo 的相同值填充先前的值:
df %>%
mutate(cutoff_date = created_at %>% date) %>%
group_by(user_id, foo, cutoff_date) %>%
tally %>%
mutate(foo_cnt = cumsum(n)) %>%
select(-n) %>%
ungroup() %>%
complete(nesting(user_id, foo), cutoff_date) %>%
arrange(user_id, cutoff_date, foo) %>%
group_by(user_id, foo) %>%
fill(foo_cnt) %>%
ungroup() %>%
group_by(user_id, cutoff_date) %>%
mutate(foo_cnt_total = sum(foo_cnt, na.rm = TRUE))
user_id foo cutoff_date foo_cnt foo_cnt_total
<dbl> <chr> <date> <int> <int>
1 1. a 2018-07-30 1 1
2 1. a 2018-07-31 3 3
3 1. a 2018-08-01 3 4
4 1. a 2018-08-02 3 5
5 1. a 2018-08-03 4 7
6 1. b 2018-07-30 NA 1
7 1. b 2018-07-31 NA 3
8 1. b 2018-08-01 1 4
9 1. b 2018-08-02 2 5
10 1. b 2018-08-03 3 7
但是,b 的值不应以NA 开头。这里需要什么?
【问题讨论】:
-
在
complete之前使用ungroup() -
@kath 谢谢,帮助很大!我添加了所需的
fill以继承前几天的值,我几乎到了我需要的地方。但是,我在尚未看到b的第一天得到NA值(请参阅更新的问题)。有什么想法吗?