检查df2中datetime列的值是否在R的df1的datateime值范围内

时间:2015-11-13 16:20:08

标签: r datetime dataframe

我有两个这样的数据框:

DF1

ID <- c("A","B","A","C","C","B","B","A")
StartDatetime <- c("2015-09-29 00:00:13", "2015-09-29 05:55:50", "2015-09-29 11:45:14", "2015-09-29 15:24:00",
                               "2015-09-29 17:24:12", "2015-09-29 21:34:31", "2015-09-29 22:22:22", "2015-09-29 23:38:22") 
EndDatetime <- c("2015-09-29 00:13:56", "2015-09-29 06:13:50", "2015-09-29 12:23:14", "2015-09-29 15:58:00",
                             "2015-09-29 17:58:17", "2015-09-29 22:06:31", "2015-09-29 22:52:28", "2015-09-29 23:55:22") 
MEASUREMENT <- c("Length","Length","Width","Length","Width","Height","Length","Height") 
df1 <- data.frame(ID,StartDatetime,EndDatetime,MEASUREMENT)

DF2

ID <- c("A","B","A","C","C","B","B")
MStart <- c("09/29/2015 00:02:13", "09/29/2015 05:56:50", "09/30/2015 11:55:14", "09/29/2015 15:33:00",
                    "09/29/2015 17:28:12", "09/29/2015 21:30:31", "09/29/2015 22:26:22") 
MEnd <- c("09/29/2015 00:11:12", "09/29/2015 06:55:50", "09/30/2015 11:54:14", "09/29/2015 15:47:00",
                  "09/29/2015 17:44:12", "09/29/2015 22:02:31", "09/29/2015 22:44:22") 
Measurement <- c("Length","Length","Width","Length","Width","Height","Length") 
df2 <- data.frame(ID,MStart,MEnd,Measurement)

我正在尝试解决一个有趣的问题,即检查ID是否具有MStart&amp;对于每次测量,df2中的MEnd在df1的日期时间范围内。逻辑回归

TRUE if (MStart & MEnd) **is within** (StartDatetime & EndDatetime)
FALSE if (MStart & MEnd) **is not within** (StartDatetime & EndDatetime)

我想要的输出将是df3,其中包含df1中的所有列,并且还添加一个具有True或False值的列。

DF3

  ID       StartDatetime         EndDatetime MEASUREMENT True_False
1  A 2015-09-29 00:00:13 2015-09-29 00:13:56      Length       TRUE
2  B 2015-09-29 05:55:50 2015-09-29 06:13:50      Length      FALSE
3  A 2015-09-29 11:55:14 2015-09-29 12:23:14       Width      FALSE
4  C 2015-09-29 15:24:00 2015-09-29 15:58:00      Length       TRUE
5  C 2015-09-29 17:24:12 2015-09-29 17:58:17       Width       TRUE
6  B 2015-09-29 21:34:31 2015-09-29 22:06:31      Height      FALSE
7  B 2015-09-29 22:22:22 2015-09-29 22:52:28      Length       TRUE
8  A 2015-09-29 23:38:22 2015-09-29 23:55:22      Height      FALSE

我在尝试转换df2的日期格式时遇到此错误而无法继续前进。

**df2$MStart <- as.POSIXct(df2$MStart,"%Y-%m-%d %H:%M:%S")**

Error in as.POSIXlt.character(as.character(x), ...) : 
  character string is not in a standard unambiguous format

请指导我如何解决这个问题。我试图使用dplyr或data.table来解决这个问题,但不知道使用日期时间的逻辑。

修改  我刚刚编辑并删除了df2的最后一行,因此它现在只有7行。我想解决这个问题,因为我的更大的数据集在df1中包含更多行,在df2中包含更少的行,因此也希望从df1返回那些具有FALSE的不匹配行。

3 个答案:

答案 0 :(得分:3)

library(dplyr)
library(lubridate)

df1_fix = 
  df1 %>%
  mutate(StartDatetime = ymd_hms(StartDatetime),
         EndDatetime = ymd_hms(EndDatetime)) %>%
  rename(Measurement = MEASUREMENT)


df2_fix = 
  df2 %>%
  mutate(MStart  = mdy_hms(MStart),
         MEnd = mdy_hms(MEnd))

initial_join = 
  df1_fix %>%
  full_join(df2_fix)

initial_join %>%
  filter(StartDatetime < EndDatetime,
         MStart < MEnd) %>%
  mutate(test = 
           int_overlaps(
             interval(StartDatetime, EndDatetime),
               interval(MStart, MEnd) ) ) %>%
  right_join(initial_join) %>%
  mutate(test = test %in% TRUE)

答案 1 :(得分:1)

library(lubridate)
df1$interval <- interval(ymd_hms(df1$StartDatetime),ymd_hms(df1$EndDatetime))
df2$interval <- interval(mdy_hms(df2$MStart),mdy_hms(df1$MEnd))
df1$True_False <- ifelse((df1$interval > df2$interval), "TRUE", "FALSE")
df1 

答案 2 :(得分:0)

这就是我要做的,这与bramtayl的解决方案类似:

library(dplyr)
library(lubridate)
df<-df1
df$StartDatetime <- ymd_hms(StartDatetime)
df$EndDatetime <- ymd_hms(EndDatetime)
df$MStart<- mdy_hms(MStart)
df$MEnd<- mdy_hms(MEnd)

df3 <- df%>%
  mutate(True_False = ifelse(MStart >StartDatetime & MStart <EndDatetime &MEnd >StartDatetime & MEnd <EndDatetime,TRUE,FALSE))