繁体   English   中英

找出R中观测值之间的时间差

[英]Finding Time Difference Between Observations in R

我正试图确定两次观察之间的时差。 数据由不同的人分解,每个人都有自己唯一的ID。 我有一个数据集,告诉我每次更改时状态更新,以及状态更改的时间。 状态可以是两个值中的一个,并且它总是更改为它不是的值(在这种情况下,从Y到N,或从N到Y)。

数据如下所示:

ID Status Time
1    Y     2013-07-01 08:07:00      
2    Y     2013-07-01 08:07:03  
3    Y     2013-07-01 08:07:04      
4    Y     2013-07-01 08:07:06      
1    N     2013-07-01 08:07:07      
2    N     2013-07-01 08:07:23      
5    Y     2013-07-01 08:07:34  
6    Y     2013-07-01 08:07:45  
7    Y     2013-07-01 08:07:47  
1    Y     2013-07-01 08:07:56  
3    N     2013-07-01 08:07:58  

我想要找到的是每个状态变化之间经过的时间量,即从Y到N需要多长时间。然后获得总结统计数据,如经过时间的分布,意味着什么经过的时间等

因此,示例输出可能如下所示,记录上面发生的三个Y到N个开关(1个切换,2个切换,3个切换)

Y to N change    Time elapsed (in seconds)
1                     7 
2                     20
3                     54

出于某种原因,我遇到了很多麻烦。 现在我有POSIXlt格式的时间,ID和状态作为一个因素。 我已经尝试使用ddply按ID排序数据,然后按时间戳排序,但到目前为止还没有用。 任何建议将不胜感激!

编辑:更改实际处于正确类型的时间。

Edit2:在等待更多答案时最终编写了一个解决方案。 我的方式比这里的许多解决方案更丑陋,但我做到了:

N <- ifelse(df$Status=="N",1,0)
Y <- ifelse(df$Status== "Y",1,0)

#making a vector which is 1 for a row if the item status of the row below it is N
var1 <- N
for (i in 1:nrow(df)) {
  var1[i] <- N[i+1]
}

#making a vector which is TRUE if a row's item status is Y and the row after is N
check <- ifelse(var1==s & var1==1,TRUE,FALSE)
#had to define the last one as FALSE manually because the for loop above would miss the last entry due to how it was constructed
check [50000]=FALSE



#made a loop which finds the time difference for a row's TIME and the row below it, given that "check " is true for that row, and writes that to a results vector.
#here is the results vector
results <- numeric(nrow(df))
#here is the for loop
for (i in 1:nrow(df)) {
  if(check [i]){
    results[i] <- difftime(df$Time[i],df$Time[i+1])
  }
}

我最初用for循环解决了这个问题,但是在我的实际数据集的大约100万行中它太慢了,所以我做了这个矢量化的东西。 这些其他解决方案是否可以处理大数据? 我一定会尝试出来的!

这是另一种方法。 我试图将所有数据保留在最终输出中。 请注意,出于演示目的,我稍微修改了您的数据。 在我的代码中,我首先按IDTime排列数据。 然后,我将Status (即Y和N)更改为0和1以创建group 在这里, group可以告诉我们Status何时更改。 如果您看到几行中的相同数字,则表示Status未更改。 然后,我计算每个ID的时间差(即gap )。 最后,我将每个组的第一行中没有出现的gap值更改为NA。 也就是说,我做了不必要的差距。 请注意,每个ID的第一次观察也有gap NA。 gap在第二位。

ann <- data.frame(ID = c(1,2,3,4,1,2,2,1,1,1,3),
                  Status = c("Y", "Y", "Y", "Y",
                             "N", "N", "Y", "Y", "Y", "N", "N"),
                  Time = c("2013-07-01 08:07:00", "2013-07-01 08:07:03",
                           "2013-07-01 08:07:04", "2013-07-01 08:07:06",
                           "2013-07-01 08:07:07", "2013-07-01 08:07:23",
                           "2013-07-01 08:07:34", "2013-07-01 08:07:45",
                           "2013-07-01 08:07:47", "2013-07-01 08:07:56",
                           "2013-07-01 08:07:58"),
                  stringsAsFactors = FALSE)

ann$Time <- as.POSIXct(ann$Time)

#   ID Status                Time
#1   1      Y 2013-07-01 08:07:00
#2   2      Y 2013-07-01 08:07:03
#3   3      Y 2013-07-01 08:07:04
#4   4      Y 2013-07-01 08:07:06
#5   1      N 2013-07-01 08:07:07
#6   2      N 2013-07-01 08:07:23
#7   2      Y 2013-07-01 08:07:34
#8   1      Y 2013-07-01 08:07:45
#9   1      Y 2013-07-01 08:07:47
#10  1      N 2013-07-01 08:07:56
#11  3      N 2013-07-01 08:07:58

ann %>%
    arrange(ID, Time) %>%
    group_by(ID) %>%
    mutate(Status = ifelse(Status == "Y", 1, 0),
           group = cumsum(c(T, diff(Status) != 0)),
           gap = Time - lag(Time)) %>%
    group_by(ID, group) %>%
    mutate(gap = ifelse(row_number() != 1, NA, gap))

#   ID Status                Time group gap
#1   1      1 2013-07-01 08:07:00     1  NA
#2   1      0 2013-07-01 08:07:07     2   7
#3   1      1 2013-07-01 08:07:45     3  38
#4   1      1 2013-07-01 08:07:47     3  NA
#5   1      0 2013-07-01 08:07:56     4   9
#6   2      1 2013-07-01 08:07:03     1  NA
#7   2      0 2013-07-01 08:07:23     2  20
#8   2      1 2013-07-01 08:07:34     3  11
#9   3      1 2013-07-01 08:07:04     1  NA
#10  3      0 2013-07-01 08:07:58     2  54
#11  4      1 2013-07-01 08:07:06     1  NA

这似乎适用于您提供的示例数据,但这些时间不是POSIXlt。 此找到的第一个Y时间和第一N时间,删除不具有由过渡任何标识YN ,并减去第一Y从第一时间N时间。

library('dplyr')

df <- read.table(text = "ID Status Time
1    Y     1
2    Y     2
3    Y     3.5
4    Y     4
1    N     5.8
2    N     6
5    Y     7
6    Y     8
7    Y     8.1
1    Y     11
3    N     12", header = TRUE)
df$ID <- as.factor(df$ID) # convert ID to factor

df %>%
  group_by(ID, Status) %>%
  summarize(Time = min(Time)) %>%
  filter("N" %in% Status & "Y" %in% Status) %>%
  summarize(Time_elapsed = Time[Status == "N"] - Time[Status == "Y"])

结果:

  ID Time_elapsed
1  1          4.8
2  2          4.0
3  3          8.5

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM