根据R中的两个日期/时间列,为列中的给定用户ID选择一个值

时间:2014-07-15 13:03:43

标签: r matching

我的数据框包含user ID'screation时间戳,date列和状态。每个用户ID都有一个创建时间戳,多个日期和每个日期的不同状态。

我需要选择与创建日期之前(或之前)最近日期对应的状态。我的数据如下:

userid    creation               date        status
0001    2014-01-01 03:30:50    2013-01-12    Red
0001    2014-01-01 12:31:12    2011-01-01    Blue
0001    2014-01-01 03:30:50    2014-05-01    Green
0002    2013-12-31 03:30:50    NA            NA
0003    2013-11-11 03:30:50    2013-11-11    Purple
0003    2013-11-11 03:30:50    2012-01-01    Red

创建时间戳和日期均为class "POSIXct" "POSIXt"

我对如何做到这一点很困惑。我很想使用包sqldf,但即使在SQL中我也不确定我是如何查询它的。数据中还有NA,只是为了让事情变得更有趣。

我发现了一些半相关的帖子,例如:Matching multiple date values in R,但没有一个足够接近我作为解决方案。

我想要输出的一个例子是:

userid    initial_status
0001      Red
0002      NA
0003      Purple

我刚刚将状态重命名为initial_status(虽然这不是必需的 - 它可以被称为状态)。

我最接近的......这在很多方面显然是错误的......是

initial_status <- sqldf("select distinct user_id, status as initial_status, date from x where date <= creation group by user_id")

我会在max(date)查询中使用date而不是sqldf,但是当我这样做时,它会将日期戳更改为一些奇怪的,不直观的数字(也许就是& #39;因为它必须将班级更改为numberic才能使用max

2 个答案:

答案 0 :(得分:2)

来源:

dat<-"userid    creation    date    status
0001    2014-01-01 03:30:50    2013-01-12    Red
0001    2014-01-01 12:31:12    2011-01-01    Blue
0001    2014-01-01 03:30:50    2014-05-01    Green
0002    2013-12-31 03:30:50    NA    NA
0003    2013-11-11 03:30:50    2013-11-11    Purple
0003    2013-11-11 03:30:50    2012-01-01    Red"
dat<-gsub(pattern = '\\s{4}',',',dat)
dat<-read.table(textConnection(dat),sep = ",",header = T)
dat$creation <-as.POSIXct(dat$creation)
dat$date <- as.POSIXct(dat$date)

使用data.table,将日期中的NA保持为最高值。

library(data.table)
# convert to data.table
dat<-as.data.table(dat)
# sort and index
setkey(dat,userid,date,creation)
# ask for the status which have the max date, by userid.
dat2<-dat[date<creation | is.na(date)][,list(statusOut=
                                               if(anyNA(date)){'noValue'
                                               }else{
                                                 as.character(.SD[which.max(date)]$status)
                                               }
                                             ),by='userid']

输出

   userid statusOut
1:      1       Red
2:      2   noValue
3:      3    Purple

答案 1 :(得分:1)

假设您的数据位于名为df的数据框中:

library(lubridate)
df$creation <- ymd_hms(df$creation)  # convert to date-time
df$date <- ymd(df$date)

library(dplyr)
df %>%
  group_by(userid) %>%  # group by userid
  filter(date <= creation) %>%  # filter by date prior to (or on) creation
  filter(row_number(creation) == 1) %>%  # filter by min creation (see ?row_number)
  select(userid, initial_status = status) # select status variable and rename