【问题标题】:Create start and endtime columns based on multiple conditions in R (dplyr, lubridate)根据 R 中的多个条件创建开始和结束时间列(dplyr,lubridate)
【发布时间】:2020-05-20 23:01:05
【问题描述】:

我有一个数据集,df

 Read      Box       ID      Time
 T         out               10/1/2019 9:00:01 AM
 T         out               10/1/2019 9:00:02 AM
 T         out               10/1/2019 9:00:03 AM
 T         out               10/1/2019 9:02:59 AM
 T         out               10/1/2019 9:03:00 AM
 F                           10/1/2019 9:05:00 AM
 T         out               10/1/2019 9:06:00 AM
 T         out               10/1/2019 9:06:02 AM
 T         in                10/1/2019 9:07:00 AM
 T         in                10/1/2019 9:07:02 AM
 T         out               10/1/2019 9:07:04 AM
 T         out               10/1/2019 9:07:05 AM
 T         out               10/1/2019 9:07:06 AM
           hello             10/1/2019 9:07:08 AM

基于此数据集中的某些条件,我想创建一个 starttime 列和一个 endtime 列。 我想在发生以下情况时创建一个“开始时间”:Read == "T", Box == "out" and ID == "" 当这种情况的第一个实例发生时,将生成一个开始时间。例如对于这个数据集,开始时间将是 10/1/2019 9:00:01 AM,因为这是我们首先看到所需条件的地方(Read = T, Box = out and ID = "" ) 但是,当这些条件中的任何一个都不成立时,就会创建结束时间。因此,第一个结束时间将发生在第 6 行之前,其中时间是 2019 年 10 月 1 日上午 9:03:00。我的最终目标是为此创建一个持续时间列。

这是我想要的输出:

  starttime                    endtime                     duration

  10/01/2019 9:00:01 AM        10/01/2019 9:03:00 AM       179 secs
  10/1/2019 9:06:00 AM         10/1/2019 9:06:02 AM        2 secs
  10/1/2019 9:07:04 AM         10/1/2019 9:07:06 AM        2 secs

输入:

  structure(list(Read = structure(c(3L, 3L, 3L, 3L, 3L, 2L, 3L, 
  3L, 3L, 3L, 4L, 4L, 3L, 1L), .Label = c("", "F", "T", "T "), class = "factor"), 
  Box = structure(c(3L, 3L, 3L, 3L, 3L, 1L, 3L, 3L, 2L, 2L, 
  3L, 3L, 3L, 1L), .Label = c("", "in", "out"), class = "factor"), 
  ID = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
  1L, 1L, 1L, 2L), .Label = c("", "hello"), class = "factor"), 
  Time = structure(1:14, .Label = c("10/1/2019 9:00:01 AM", 
 "10/1/2019 9:00:02 AM", "10/1/2019 9:00:03 AM", "10/1/2019 9:02:59 AM", 
 "10/1/2019 9:03:00 AM", "10/1/2019 9:05:00 AM", "10/1/2019 9:06:00 AM", 
 "10/1/2019 9:06:02 AM", "10/1/2019 9:07:00 AM", "10/1/2019 9:07:02 AM", 
 "10/1/2019 9:07:04 AM", "10/1/2019 9:07:05 AM", "10/1/2019 9:07:06 AM", 
 "10/1/2019 9:07:08 AM"), class = "factor")), class = "data.frame", row.names = c(NA, 
 -14L))

我认为总的来说,我必须创建一个循环。我相信我的思维过程是正确的,只是不确定如何制定代码。这就是我正在尝试的:

 df2 <- mutate(df,
      Date = lubridate::mdy_hms(Date))




   for ( i in 2:nrow(df2))
    {
  if(df2$Read[[i]] == 'T')

     }

我认为这可能是一个开始(只是将我的条件放在循环中,我不知道如何完成)

欢迎提出任何建议。

【问题讨论】:

    标签: r loops dplyr lubridate


    【解决方案1】:

    您可以在没有循环的情况下执行此操作。使用dplyr,因为使用管道很容易做很多事情。

    我们首先将Time 列转换为POSIXct 类,创建一个cond 列,它根据我们要检查的条件给出逻辑值,创建一个列以使用cond 列的累积和创建组。只保留满足条件的行,并获得Timefirstlast 值以及每组它们之间的差异。

    library(dplyr)
    
    df %>%
      mutate(Time = lubridate::mdy_hms(Time), 
             cond = Read == "T" & Box == "out" & ID == "", 
             grp = cumsum(!cond)) %>%
      filter(cond) %>%
      group_by(grp) %>%
      summarise(starttime = first(Time), 
                endtime = last(Time), 
                duration = difftime(endtime, starttime, units = "secs")) %>%
      select(-grp)
    
    # A tibble: 3 x 3
    #  starttime           endtime             duration
    #  <dttm>              <dttm>              <drtn>  
    #1 2019-10-01 09:00:01 2019-10-01 09:03:00 179 secs
    #2 2019-10-01 09:06:00 2019-10-01 09:06:02   2 secs
    #3 2019-10-01 09:07:04 2019-10-01 09:07:06   2 secs
    

    数据

    我已经清理了你的数据并将其用作df

    df <- structure(list(Read = c("T", "T", "T", "T", "T", "F", "T", "T", 
    "T", "T", "T", "T", "T", ""), Box = c("out", "out", "out", "out", 
    "out", "", "out", "out", "in", "in", "out", "out", "out", "hello"
    ), ID = c("", "", "", "", "", "", "", "", "", "", "", "", "", 
    ""), Time = c("10/1/2019 9:00:01 AM", "10/1/2019 9:00:02 AM", 
    "10/1/2019 9:00:03 AM", "10/1/2019 9:02:59 AM", "10/1/2019 9:03:00 AM", 
    "10/1/2019 9:05:00 AM", "10/1/2019 9:06:00 AM", "10/1/2019 9:06:02 AM", 
    "10/1/2019 9:07:00 AM", "10/1/2019 9:07:02 AM", "10/1/2019 9:07:04 AM", 
    "10/1/2019 9:07:05 AM", "10/1/2019 9:07:06 AM", "10/1/2019 9:07:08 AM"
    )), row.names = c(NA, -14L), class = "data.frame")
    

    【讨论】:

    • 这很好用!因此,据我了解,每当您希望使用 dplyr 在代码中添加条件时,都可以使用“cond”函数?
    • cond 在这里只是一个占位符列,它告诉我们该行是否满足我们正在检查的条件。如果您需要添加更多条件,可以在其中添加&amp;
    • 您好,@Ronak,我可以将其添加到代码中以过滤某个值吗? cond = Subject == "^RE|FWD|FW", ignore.case = TRUE 以及 cond = Subject !== "^RE|FWD|FW", ignore.case = TRUE 的不同场景
    • 如果要查找模式,不能使用==!=,请使用grepl
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-18
    • 1970-01-01
    • 2019-12-06
    • 1970-01-01
    相关资源
    最近更新 更多