R中没有夜间的行之间的时差

R中没有夜间的行之间的时差,r,time-series,R,Time Series,一名受试者在几天内的几个时间点进行测量。我有一行“resptime_s”(受试者在智能手机上听到嘟嘟声的时间)。现在我想知道这些时间之间的平均时间(也就是本专栏的两行之间的时间)和夜间时间(夜间时间总是从晚上22:30到早上7:30)。例如: R脚本: setwd("C:/Users/Hanne/Desktop/") dat <- read.csv(file="datnew2.csv", sep=";",header=TRUE) rows <- c(1:388) #time p

一名受试者在几天内的几个时间点进行测量。我有一行“resptime_s”(受试者在智能手机上听到嘟嘟声的时间)。现在我想知道这些时间之间的平均时间(也就是本专栏的两行之间的时间)和夜间时间(夜间时间总是从晚上22:30到早上7:30)。例如:

R脚本:

 setwd("C:/Users/Hanne/Desktop/")
 dat <- read.csv(file="datnew2.csv", sep=";",header=TRUE)
 rows <- c(1:388) #time points
 columns <- c(2,60) # datum and time
 nVariables = 2
 newdata<-dat[rows,columns]
 head(newdata)
 fun2 <- function(x){
      bt <- as.integer(sub("(^\\d{1,2}):.*", "\\1", x))
      f <- cumsum(c(FALSE, diff(bt) < 0))
      d <- rep(as.Date("2018-01-01"), length.out = length(bt))
      bt <- as.POSIXct(paste(d, x))
      res <- sapply(split(bt, f), function(b) c(0, difftime(b[-1], b[1])))
      unname(unlist(res))
    }
fun2(newdata$resptime_s)
我获得了以下输出:

尝试以下方法。它粘贴一个日期,该日期在下一个小时小于上一个小时时递增。然后
difftime
按预期工作

fun <- function(x){
    bt <- as.integer(sub("(^\\d{1,2}):.*", "\\1", x))
    inx <- as.logical(cumsum(c(FALSE, diff(bt) < 0)))
    d <- rep(as.Date("2018-01-01"), length.out = length(bt))
    d[inx] <- d[inx] + 1

    beeptime <- as.POSIXct(paste(d, x))
    difftime(beeptime[-1], beeptime[1])
}

fun(newdata$beeptime)
#Time differences in hours
#[1]  2.716667  3.633333  8.833333 14.283333 23.100000 25.166667

fun另一种方法是使用
lubridate
软件包将
beeptime
midnight
转换为偏移量(以秒为单位)

然后,我们可以编写一个函数来计算不包括夜间的时间差(
22:30-7:30

在开始解决方案之前,让我们先看看
7:30和22:30的偏移量(以秒为单位)

library(lubridate)
as.numeric(seconds(hm("7:30")))
# [1] 27000
as.numeric(seconds(hm("22:30")))
# [1] 81000
我编写了两组函数来计算两次之间的差值:

# Function checks individual time and shifts them to night boundary. So that 
# time over night can be excluded. 
checkNightBoundry <- function(val){
  if(val < 27000){
    val = 27000
  } else if(val > 81000) {
    val = 81000
  }
  val
}

# Arguments are offset from midnight in seconds  
# Calculate difference between two time, excluding midtime
calcDifftime <- function(currVal, prevVal){
  diffTime <- 0
  currVal = checkNightBoundry(currVal)
  prevVal = checkNightBoundry(prevVal)

  if(currVal > prevVal){
    diffTime = currVal - prevVal 
  }else if(currVal < prevVal){
    diffTime = (81000 - prevVal) + (currVal - 27000)
  }

  diffTime
}
数据:

df <- read.table(text = 
"timepoint    beeptime
1             08:30
2             11:13
3             12:08
4             17:20
5             22:47
6             7:36
7             9:40",
header = TRUE, stringsAsFactors = FALSE)

df在
lubridate
中使用不同的函数处理时间间隔,提供了最优雅、最容易理解的解决方案

library(tidyverse)
library(lubridate)

data <- tribble(
  ~time_point,    ~beeptime,
  1,             "08:30",
  2,             "11:13",
  3,             "12:08",
  4,             "17:20",
  5,             "22:47",
  6,             "7:36",
  7,             "9:40"
) %>%
  mutate(beeptime = as_datetime(hm(beeptime)))

晚上出去玩是什么意思?我的意思是什么是夜间时间的定义?晚上10:30到早上7:30之间的时间(22h30-7h30)。出现了两个错误:错误:UseMethod(“mutate”)中的“#[1]27000 as.numeric”错误中出现了意外符号(“mutate”):没有适用于类“function”@user9780154的对象的“mutate”方法在第
行库(lubridate)中出现了打字错误
。我在回答中已经改正了。看一看。我建议先在示例数据上使用它来理解逻辑。你知道我是否可以加载数据而不是在tribble中使用数据框吗?因为我的真实数据由388个时间点组成。是的。第2步和第3步只是假设beeptime是一种日期时间格式(例如使用
as_datetime()
as.POSIXct()
)。如果你有几个病人,那么在计算时间间隔之前,
group\u by(patient)
。@MikaelPoulJohannesson很好的解决方案。我以为OP想知道哔哔声在
夜间
之间经过的时间。但,若这种情况在夜间发生,那个么这个想法似乎是忽略蜂鸣音本身。
# Function checks individual time and shifts them to night boundary. So that 
# time over night can be excluded. 
checkNightBoundry <- function(val){
  if(val < 27000){
    val = 27000
  } else if(val > 81000) {
    val = 81000
  }
  val
}

# Arguments are offset from midnight in seconds  
# Calculate difference between two time, excluding midtime
calcDifftime <- function(currVal, prevVal){
  diffTime <- 0
  currVal = checkNightBoundry(currVal)
  prevVal = checkNightBoundry(prevVal)

  if(currVal > prevVal){
    diffTime = currVal - prevVal 
  }else if(currVal < prevVal){
    diffTime = (81000 - prevVal) + (currVal - 27000)
  }

  diffTime
}
library(dplyr)
library(lubridate)

df %>% mutate(beeptimeOffset = as.numeric(seconds(hm(beeptime)))) %>%
  mutate(diffTime = mapply(calcDifftime, 
         beeptimeOffset, lag(beeptimeOffset, default = first(beeptimeOffset)))/3600) 

# timepoint  beeptime beeptimeOffset(sec) diffTime(hrs)
# 1         1    08:30          30600    0.0000000
# 2         2    11:13          40380    2.7166667
# 3         3    12:08          43680    0.9166667
# 4         4    17:20          62400    5.2000000
# 5         5    22:47          82020    5.1666667
# 6         6     7:36          27360    0.1000000
# 7         7     9:40          34800    2.0666667
df <- read.table(text = 
"timepoint    beeptime
1             08:30
2             11:13
3             12:08
4             17:20
5             22:47
6             7:36
7             9:40",
header = TRUE, stringsAsFactors = FALSE)
library(tidyverse)
library(lubridate)

data <- tribble(
  ~time_point,    ~beeptime,
  1,             "08:30",
  2,             "11:13",
  3,             "12:08",
  4,             "17:20",
  5,             "22:47",
  6,             "7:36",
  7,             "9:40"
) %>%
  mutate(beeptime = as_datetime(hm(beeptime)))
day <- interval(
  as_datetime(hm("07:30")),
  as_datetime(hm("22:30"))
)
# %--% is basically the same as interval() above.
data_interval <-
  data %>%
  filter(beeptime %within% day) %>%
  mutate(beep_interval = lag(beeptime) %--% beeptime)
# You can use as.numeric() to extract (e.g.) minutes, which you can
# just pass to mean().
data_interval$beep_interval %>%
  as.numeric("minutes") %>%
  abs() %>%
  mean(na.rm = TRUE)

#> [1] 247.6