【发布时间】:2021-10-22 06:22:27
【问题描述】:
我正在尝试在 R 中解决以下 Leetcode SQL 数据库问题。
问题:编写一个 R 查询,报告从今天起最多 90 天内的每个日期,该日期首次登录的用户数。假设今天是 2019-06-30。
链接到 Leetcode 问题:https://leetcode.com/problems/new-users-daily-count/
数据如下所示:
Traffic <- cbind.data.frame(user_id = c(1,1,1,2,2,3,3,3,4,4,4,5,5,5,5),
activity = c("login","homepage","logout","login","logout","login","jobs",
"logout","login","groups","logout","login","logout","login",
"logout"),
activity_date = c("2019-05-01","2019-05-01","2019-05-01","2019-06-21",
"2019-06-21","2019-01-01","2019-01-01","2019-01-01",
"2019-06-21","2019-06-21","2019-06-21","2019-03-01",
"2019-03-01","2019-06-21","2019-06-21"))
我在 R 中使用 lubridate() 和 dplyr() 尝试了两种方法
方法一:使用interval()和as.period()函数。
library("lubridate")
library("plyr")
library("dplyr")
library("data.table")
Today = lubridate::ymd("2019-06-30")
Traffic %>% dplyr::filter(activity == "login") %>% dplyr::filter(lubridate::day(lubridate::as.period(lubridate::interval(Today, lubridate::ymd(activity_date)), unit = "days")) <= 90) %>%
plyr::ddply(.(user_id), transform, rank = rank(activity_date, ties.method = "min")) %>%
dplyr::filter(rank == 1) %>% dplyr::group_by(activity_date) %>%
dplyr::summarise(user_count = n())
方法二:
Traffic %>% dplyr::filter(activity == "login") %>% dplyr::filter(abs(lubridate::day(Today) - lubridate::day(lubridate::ymd(activity_date))) <= 90 &
abs(lubridate::month(Today) - lubridate::month(lubridate::ymd(activity_date))) < 3) %>%
plyr::ddply(.(user_id), transform, rank = rank(activity_date, ties.method = "min")) %>%
dplyr::filter(rank == 1) %>% dplyr::group_by(activity_date) %>%
dplyr::summarise(user_count = n())
我想找出方法 1 不起作用的原因以及方法 2 的第二行计数错误的原因。
【问题讨论】:
-
你应该避免使用
plyr。 -
嗨,当然!您将如何使用 dplyr 的窗口函数解决问题的排名部分?
-
嗨,马丁,您能否更具体地说明为什么要避免使用 plyr?我发现它对于在子组中排名非常有用。是不是比 dplyr 慢,效率低?
-
您的第一个解决方案不起作用,因为日期间隔产生负数(它们是过去的)。将比较设置为
>= -90应该可以。 -
我认为
plyr的大多数函数在dplyr中都有类似的实现,但它们会相互屏蔽某些函数。我从来没有错过plyr。
标签: r date time dplyr lubridate