Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在R中匹配多个日期值_R_Matching_Plyr - Fatal编程技术网

在R中匹配多个日期值

在R中匹配多个日期值,r,matching,plyr,R,Matching,Plyr,我有以下数据框架DF,描述在特定日期参与项目的人员: ID ProjectName StartDate 1 Health 3/1/06 18:20 2 Education 2/1/07 15:30 1 Education 5/3/09 9:00 3 Wellness 4/1/10 12:00 2 Health 6/1/11 14:20 目标是找到与每个ID对应的第一个

我有以下数据框架DF,描述在特定日期参与项目的人员:

ID    ProjectName    StartDate 
1       Health        3/1/06 18:20
2       Education     2/1/07 15:30
1       Education     5/3/09 9:00
3       Wellness      4/1/10 12:00
2       Health        6/1/11 14:20
目标是找到与每个ID对应的第一个项目。例如,预期输出如下:

ID    ProjectName    StartDate 
1       Health        3/1/06 18:20
2       Education     2/1/07 15:30
3       Wellness      4/1/10 12:00
到目前为止,我已经做了以下工作来获取每个ID的第一个起始日期:

sub <- ddply(DF, .(ID), summarise, st = min(as.POSIXct(StartDate)));

sub这是一个基本的R解决方案

dat <- data.frame(
    ID=c(1,2,1,3,2), 
    PRJ=c("H","E","E", "W", "H"), 
    START=strptime(
      c(
        "3/1/06 18:20", "2/1/07 15:30", "5/3/09 9:00",
        "4/1/10 12:00","6/1/11 14:20"), 
      "%d/%m/%y %H:%M")
    )
min_date <- function(x) {x[which.min(x$START), ]}
s <- split(dat, dat$ID) # split
a <- lapply(s, FUN=min_date) # apply
do.call("rbind", a) # combine
然而,@SimonO101的订单匹配解决方案要比这快得多

为了好玩,下面是另一个使用
sqldf
的解决方案:

sqldf("select * from dat group by ID having START=min(START)")

这是一个
data.table
解决方案,应该非常有效

DF <- data.frame(ID=c(1,2,1,3,2,1), ProjectName=c('Health', 'Education', 'Education', 'Wellness', 'Health', 'Health'),
             StartDate=c('3/1/06 18:20', '2/1/07 15:30', '5/3/09 9:00', '4/1/10 12:00', '6/1/11 14:20', '1/1/06 11:10'))

使用
match
非常简单,因为
match
返回:

其第一个参数的第一个匹配位置的向量 第二个

因此,您所需要做的就是按日期排序,然后使用
unique
获取每个ID的一个实例,并
match
找到第一个位置。感谢@MatthewLunberg为您的数据提供了一个可复制的示例:

DF <- DF[ order(as.POSIXct(DF$StartDate, format="%m/%d/%y %H:%M")) , ]
DF[ match( unique( DF$ID ) , DF$ID ) , ]
#  ID ProjectName    StartDate
#6  1      Health 1/1/06 11:10
#2  2   Education 2/1/07 15:30
#4  3    Wellness 4/1/10 12:00

DF为了对其进行取整,这里有一个基于
plyr
包的解决方案。我添加了一个额外的列,使
textConnection
更容易读取数据

dfProjects = as.data.frame(read.table(textConnection("ID    ProjectName    Date Time 
  1       Health        3/1/06 18:20
  2       Education     2/1/07 15:30
  1       Education     5/3/09 9:00
  3       Wellness      4/1/10 12:00
  2       Health        6/1/11 14:20"), header = TRUE))
ddply(within(dfProjects, dfProjects[order(
  as.POSIXct(paste(Date, Time), format = "%m/%d/%y %H:%M")), ]), 
      .(ID), function(dataFrame) dataFrame[1, ])

+1对于OP数据和data.table解决方案的可复制示例,这似乎是最快的解决方案。
plyr
已被封存,支持
dplyr
,但
DF%>%group\u by(ID)%%>%first()
有效
d[,.SD[1,],by=ID]
DF <- DF[ order(as.POSIXct(DF$StartDate, format="%m/%d/%y %H:%M")) , ]
DF[ match( unique( DF$ID ) , DF$ID ) , ]
#  ID ProjectName    StartDate
#6  1      Health 1/1/06 11:10
#2  2   Education 2/1/07 15:30
#4  3    Wellness 4/1/10 12:00
dfProjects = as.data.frame(read.table(textConnection("ID    ProjectName    Date Time 
  1       Health        3/1/06 18:20
  2       Education     2/1/07 15:30
  1       Education     5/3/09 9:00
  3       Wellness      4/1/10 12:00
  2       Health        6/1/11 14:20"), header = TRUE))
ddply(within(dfProjects, dfProjects[order(
  as.POSIXct(paste(Date, Time), format = "%m/%d/%y %H:%M")), ]), 
      .(ID), function(dataFrame) dataFrame[1, ])