得到R中有条件的组的行号

  • 本文关键字:有条件 得到 r dplyr
  • 更新时间 :
  • 英文 :


我有一个按用户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以获得相同的效果。(

最新更新