在 R 中以 %H:%M:%S 格式计算时间差
Calculate time difference in %H:%M:%S format in R
我正在尝试计算满足特定条件的行的 2 列之间的时间差。
dates1 <- c("1899-12-31 12:20:00 PMT", "1899-12-31 15:30:00 PMT", "1899-12-31 13:20:00 PMT", "1899-12-31 11:50:00 PMT",
NA)
dates2 <- c("1899-12-31 11:13:00 PMT", "1899-12-31 11:41:00 PMT", "1899-12-31 14:04:00 PMT", "1899-12-31 13:03:00 PMT",
"1899-12-31 13:18:00 PMT")
site <- c(15, 16, 18, 18,
15)
DS <- as.data.frame(cbind(site, dates1 , dates2))
## convert to POSIXct format
DS[, 2:3] <- lapply(DS[, 2:3], function(x) as.POSIXct(strptime(x,"%Y-%m-%d %H:%M:%S ",tz="")))
## create a new columns with the time difference between dates1 and dates2 in %H:%M:%S format if site=18 , else take value from column dates1
DS$output <- ifelse(DS$site ==18,
difftime(DS$dates1, DS$dates2, units = "mins"),
DS$dates1)
## using the code above doesnt work because:
#1- using the difftime function I can't choose the "%H:%M:%S" for the output
#2- for sites != 18, the dates1 lose its "%H:%M:%S format
# I have also tried to use:
DS$output <- ifelse(DS$site ==18,
difftime(DS$dates1, DS$dates2, units = "mins"),
0)
## and then convert the difference in minutes to %H:%M:%S format using
DS$output<- as.difftime(DS$output , format = "%H:%M:%S", units = "mins")
## but it doesnt work.
## the output should be something like:
output<- c("12:20:00", "15:30:00","00:44:00", "01:13:00", NA)
DS.out <- cbind(DS, output)
> DS.out
site dates1 dates2 output
1 15 1899-12-31 12:20:00 PMT 1899-12-31 11:13:00 PMT 12:20:00
2 16 1899-12-31 15:30:00 PMT 1899-12-31 11:41:00 PMT 15:30:00
3 18 1899-12-31 13:20:00 PMT 1899-12-31 14:04:00 PMT 00:44:00
4 18 1899-12-31 11:50:00 PMT 1899-12-31 13:03:00 PMT 01:13:00
5 15 <NA> 1899-12-31 13:18:00 PMT <NA>
#Where output is the time difference calculated for rows 3 and 4 (site=18)
#or a copy of the time from dates 1 for the other rows (with sites different from 18).
有没有用不同的函数计算 H%:%M:%S 格式的时差?
这样的东西行得通吗?
with(DS, ifelse(site == 18, as.character(lubridate::seconds_to_period(
difftime(dates2, dates1, units = "secs"))),
format(dates1, "%T")))
#[1] "12:20:00" "15:30:00" "44M 0S" "1H 13M 0S" NA
您可以使用 chron 库中的 "times" 格式。
(这不是很简单,但似乎可行)
# get the difference in minutes
DS$Time1NEW <- ifelse(DS$site ==18,
difftime(DS$dates1, DS$dates2, units = "mins"),
NA)
# get the absolute value
DS$Time1NEW<-abs(DS$Time1NEW)
# conver to hours:min:sec using "times" from library chron
DS$hours_minutes<-times((DS$Time1NEW%/%60 + DS$Time1NEW%%60 /60)/24)
# convert the others (not in site 18)
DS$no18<-times(paste0(hours(DS$dates1),':', minutes(DS$dates1),':', seconds(DS$dates1)))
# create final data column
DS$final<-DS$hours_minutes
# now substitute when necessary
wh<-which(is.na(DS$final))
DS$final[wh]<-DS$no18[wh]
这就是你得到的:
> head(DS)
site dates1 dates2 Time1NEW hours_minutes no18 final
1 15 1899-12-31 12:20:00 PMT 1899-12-31 11:13:00 PMT NA <NA> 12:20:00 12:20:00
2 16 1899-12-31 15:30:00 PMT 1899-12-31 11:41:00 PMT NA <NA> 15:30:00 15:30:00
3 18 1899-12-31 13:20:00 PMT 1899-12-31 14:04:00 PMT 44 00:44:00 13:20:00 00:44:00
4 18 1899-12-31 11:50:00 PMT 1899-12-31 13:03:00 PMT 73 01:13:00 11:50:00 01:13:00
5 15 <NA> 1899-12-31 13:18:00 PMT NA <NA> <NA> <NA>
您可以在小时内使用 difftime
; floor
和 %% 1
将小时和分钟 paste
放在一起。不过需要进行一些舍入。
DS$output[DS$site == 18] <- {
tmp <- as.numeric(round(with(DS[DS$site == 18, ], difftime(dates2, dates1, units="hours")), 2))
paste(sprintf("%02d", floor(tmp)), round(tmp %% 1 * 60), "00", sep=":")
}
DS$output[site != 18] <- strftime(DS$dates1[DS$site != 18], "%T")
DS
# site dates1 dates2 output
# 1 15 1899-12-31 12:20:00 1899-12-31 11:13:00 12:20:00
# 2 16 1899-12-31 15:30:00 1899-12-31 11:41:00 15:30:00
# 3 18 1899-12-31 13:20:00 1899-12-31 14:04:00 00:44:00
# 4 18 1899-12-31 11:50:00 1899-12-31 13:03:00 01:13:00
# 5 15 <NA> 1899-12-31 13:18:00 <NA>
您可以使用 hms
库。
require(hms)
x <- data.frame(TIME_SPENT = as.difftime(runif(10) * 10, format = 'H', units = 'hours'))
x$TIME_SPENT_HMS <- hms(hours = as.numeric(x$TIME_SPENT))
> x
TIME_SPENT TIME_SPENT_HMS
1 0.670335 hours 00:40:13.206023
2 6.740590 hours 06:44:26.122495
3 9.433242 hours 09:25:59.670743
4 9.350243 hours 09:21:00.873019
5 1.459504 hours 01:27:34.214544
6 4.820711 hours 04:49:14.560171
7 5.052186 hours 05:03:07.870653
8 9.415136 hours 09:24:54.489527
9 4.717802 hours 04:43:04.086949
10 4.131969 hours 04:07:55.087836
它支持 class difftime 的对象(但单位总是秒)并以 HH:MM:SS 格式存储值。
> class(x$TIME_SPENT_HMS)
[1] "hms" "difftime"
您可以对其进行各种计算。
> x$TIME_SPENT_HMS[1] + 10
Time difference of 2423.206 secs
table 视图中显示的值也用分号表示:
我正在尝试计算满足特定条件的行的 2 列之间的时间差。
dates1 <- c("1899-12-31 12:20:00 PMT", "1899-12-31 15:30:00 PMT", "1899-12-31 13:20:00 PMT", "1899-12-31 11:50:00 PMT",
NA)
dates2 <- c("1899-12-31 11:13:00 PMT", "1899-12-31 11:41:00 PMT", "1899-12-31 14:04:00 PMT", "1899-12-31 13:03:00 PMT",
"1899-12-31 13:18:00 PMT")
site <- c(15, 16, 18, 18,
15)
DS <- as.data.frame(cbind(site, dates1 , dates2))
## convert to POSIXct format
DS[, 2:3] <- lapply(DS[, 2:3], function(x) as.POSIXct(strptime(x,"%Y-%m-%d %H:%M:%S ",tz="")))
## create a new columns with the time difference between dates1 and dates2 in %H:%M:%S format if site=18 , else take value from column dates1
DS$output <- ifelse(DS$site ==18,
difftime(DS$dates1, DS$dates2, units = "mins"),
DS$dates1)
## using the code above doesnt work because:
#1- using the difftime function I can't choose the "%H:%M:%S" for the output
#2- for sites != 18, the dates1 lose its "%H:%M:%S format
# I have also tried to use:
DS$output <- ifelse(DS$site ==18,
difftime(DS$dates1, DS$dates2, units = "mins"),
0)
## and then convert the difference in minutes to %H:%M:%S format using
DS$output<- as.difftime(DS$output , format = "%H:%M:%S", units = "mins")
## but it doesnt work.
## the output should be something like:
output<- c("12:20:00", "15:30:00","00:44:00", "01:13:00", NA)
DS.out <- cbind(DS, output)
> DS.out
site dates1 dates2 output
1 15 1899-12-31 12:20:00 PMT 1899-12-31 11:13:00 PMT 12:20:00
2 16 1899-12-31 15:30:00 PMT 1899-12-31 11:41:00 PMT 15:30:00
3 18 1899-12-31 13:20:00 PMT 1899-12-31 14:04:00 PMT 00:44:00
4 18 1899-12-31 11:50:00 PMT 1899-12-31 13:03:00 PMT 01:13:00
5 15 <NA> 1899-12-31 13:18:00 PMT <NA>
#Where output is the time difference calculated for rows 3 and 4 (site=18)
#or a copy of the time from dates 1 for the other rows (with sites different from 18).
有没有用不同的函数计算 H%:%M:%S 格式的时差?
这样的东西行得通吗?
with(DS, ifelse(site == 18, as.character(lubridate::seconds_to_period(
difftime(dates2, dates1, units = "secs"))),
format(dates1, "%T")))
#[1] "12:20:00" "15:30:00" "44M 0S" "1H 13M 0S" NA
您可以使用 chron 库中的 "times" 格式。
(这不是很简单,但似乎可行)
# get the difference in minutes
DS$Time1NEW <- ifelse(DS$site ==18,
difftime(DS$dates1, DS$dates2, units = "mins"),
NA)
# get the absolute value
DS$Time1NEW<-abs(DS$Time1NEW)
# conver to hours:min:sec using "times" from library chron
DS$hours_minutes<-times((DS$Time1NEW%/%60 + DS$Time1NEW%%60 /60)/24)
# convert the others (not in site 18)
DS$no18<-times(paste0(hours(DS$dates1),':', minutes(DS$dates1),':', seconds(DS$dates1)))
# create final data column
DS$final<-DS$hours_minutes
# now substitute when necessary
wh<-which(is.na(DS$final))
DS$final[wh]<-DS$no18[wh]
这就是你得到的:
> head(DS)
site dates1 dates2 Time1NEW hours_minutes no18 final
1 15 1899-12-31 12:20:00 PMT 1899-12-31 11:13:00 PMT NA <NA> 12:20:00 12:20:00
2 16 1899-12-31 15:30:00 PMT 1899-12-31 11:41:00 PMT NA <NA> 15:30:00 15:30:00
3 18 1899-12-31 13:20:00 PMT 1899-12-31 14:04:00 PMT 44 00:44:00 13:20:00 00:44:00
4 18 1899-12-31 11:50:00 PMT 1899-12-31 13:03:00 PMT 73 01:13:00 11:50:00 01:13:00
5 15 <NA> 1899-12-31 13:18:00 PMT NA <NA> <NA> <NA>
您可以在小时内使用 difftime
; floor
和 %% 1
将小时和分钟 paste
放在一起。不过需要进行一些舍入。
DS$output[DS$site == 18] <- {
tmp <- as.numeric(round(with(DS[DS$site == 18, ], difftime(dates2, dates1, units="hours")), 2))
paste(sprintf("%02d", floor(tmp)), round(tmp %% 1 * 60), "00", sep=":")
}
DS$output[site != 18] <- strftime(DS$dates1[DS$site != 18], "%T")
DS
# site dates1 dates2 output
# 1 15 1899-12-31 12:20:00 1899-12-31 11:13:00 12:20:00
# 2 16 1899-12-31 15:30:00 1899-12-31 11:41:00 15:30:00
# 3 18 1899-12-31 13:20:00 1899-12-31 14:04:00 00:44:00
# 4 18 1899-12-31 11:50:00 1899-12-31 13:03:00 01:13:00
# 5 15 <NA> 1899-12-31 13:18:00 <NA>
您可以使用 hms
库。
require(hms)
x <- data.frame(TIME_SPENT = as.difftime(runif(10) * 10, format = 'H', units = 'hours'))
x$TIME_SPENT_HMS <- hms(hours = as.numeric(x$TIME_SPENT))
> x
TIME_SPENT TIME_SPENT_HMS
1 0.670335 hours 00:40:13.206023
2 6.740590 hours 06:44:26.122495
3 9.433242 hours 09:25:59.670743
4 9.350243 hours 09:21:00.873019
5 1.459504 hours 01:27:34.214544
6 4.820711 hours 04:49:14.560171
7 5.052186 hours 05:03:07.870653
8 9.415136 hours 09:24:54.489527
9 4.717802 hours 04:43:04.086949
10 4.131969 hours 04:07:55.087836
它支持 class difftime 的对象(但单位总是秒)并以 HH:MM:SS 格式存储值。
> class(x$TIME_SPENT_HMS)
[1] "hms" "difftime"
您可以对其进行各种计算。
> x$TIME_SPENT_HMS[1] + 10
Time difference of 2423.206 secs
table 视图中显示的值也用分号表示: