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