我有一个按用户ID和日期排序的数据帧,如下所示:
df <- data.frame(
userid = c("1", "1", "1", "2", "2", "3", "3"),
date = c("2016-10-23", "2018-01-01", "2020-03-03", "2008-09-04", "2021-08-08", "2019-10-02", "2022-01-02")
)
userid date
1 2016-10-23
1 2018-01-01
1 2020-03-03
2 2008-09-04
2 2021-08-08
3 2019-10-02
3 2022-01-02
我想按用户ID分组并分配行号,但2017年之前的任何内容都应该是行号0:
df2 <- data.frame(
userid = c("1", "1", "1", "2", "2", "3", "3"),
date = c("2016-10-23", "2018-01-01", "2020-03-03", "2008-09-04", "2021-08-08", "2019-10-02", "2022-01-02"),
rownumber = c("0", "1", "2", "0", "1", "1", "2")
)
userid date rownumber
1 2016-10-23 0
1 2018-01-01 1
1 2020-03-03 2
2 2008-09-04 0
2 2021-08-08 1
3 2019-10-02 1
3 2022-01-02 2
如您所见,2016年和2008年的日期已指定为0,行号从1开始递增,不包括这些日期。
我尝试过以下操作,但它不会将0分配给2017年之前的日期。
df %>%
group_by(userid) %>%
mutate(rownumber = row_number()) %>%
ungroup()
谢谢!
您可以从日期中提取年份。对于每个userid
,将行号减去为<=
2017的值的数目。
library(dplyr)
df %>%
mutate(date = as.Date(date),
year = lubridate::year(date)) %>%
arrange(userid, date) %>%
group_by(userid) %>%
mutate(rownumber = pmax(row_number() - sum(year <= 2017), 0)) %>%
ungroup
# userid date year rownumber
# <chr> <date> <dbl> <int>
#1 1 2016-10-23 2016 0
#2 1 2018-01-01 2018 1
#3 1 2020-03-03 2020 2
#4 2 2008-09-04 2008 0
#5 2 2021-08-08 2021 1
#6 3 2019-10-02 2019 1
#7 3 2022-01-02 2022 2
df %>%
mutate(date = as.Date(date)) %>%
group_by(userid, year = (1900+as.POSIXlt(date)$year) < 2018) %>%
mutate(rownumber = if (year[1]) 0 else order(date)) %>%
ungroup() %>%
select(-year)
# # A tibble: 7 x 3
# userid date rownumber
# <chr> <date> <dbl>
# 1 1 2016-10-23 0
# 2 1 2018-01-01 1
# 3 1 2020-03-03 2
# 4 2 2008-09-04 0
# 5 2 2021-08-08 1
# 6 3 2019-10-02 1
# 7 3 2022-01-02 2
我本可以用row_number()
代替order(date)
,但我不确定你的数据是否被预先排序。您可以使用row_number()
来获得相同的结果此处。
(仅供参考,您的date
是一个字符串,所以我也将其转换为一个适当的Date
类,无论好坏。如果您不想这样做,您可以将第一个mutate
和(1900+...)<2018
替换为as.integer(substring(date,1,4)) < 2018
以获得相同的效果。(