我的数据框包含user ID's
,creation
时间戳,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
。
答案 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