从 CSV 导入持续时间
Import duration from CSV
我有一个 CSV 文件,其中包含我想导入到 R 中的通话记录,例如通话时间、被叫号码、通话时长等。
CSV 文件中 'Duration of the call' 字段的格式类似于 1d02:03:04 即 1 天 2 小时 3 分 4 秒。
我可以使用 df.duration = pd.to_timedelta(df.duration)
在 Python Pandas 中轻松地将 Duration 字段转换为 Duration 对象。
转换后,我可以通过将开始时间加上持续时间来获得停止时间。
我正在寻找 R 中相同的等效项以将 1d02:03:04 转换为持续时间对象,以便我可以获得结束时间。
或者,您也可以为此使用 regex
(即使其他解决方案,例如 lubridate
可能更好):
首先创建模式 ^(\d*)d(\d*):?(\d*):?(\d*)$
(可能需要根据您的格式进行调整)以提取持续时间的天数、小时数、分钟数和秒数。然后,您可以根据此信息添加开始时间。
fun = function (start_time, duration) {
# Check start_time
if (!'POSIXct' %in% class(start_time))
stop('Expect "start_time" to be of class "POSIXct"')
# Regex pattern for extraction of days, hours, minutes & seconds
pattern = '^(\d*)d(\d*):?(\d*):?(\d*)$'
# Extract data
days = as.integer(gsub(pattern, '\1', duration))
hours = as.integer(gsub(pattern, '\2', duration))
minutes = as.integer(gsub(pattern, '\3', duration))
seconds = as.integer(gsub(pattern, '\4', duration))
# Maybe add some safety measures just in case e.g. ifelse(is.na(seconds ), 0L, seconds)
# Add (in seconds)
final_time = start_time + seconds + minutes*60 + hours*60*60 + days*60*60*24
return (final_time)
}
这是一个带有向量的小例子
durations = c('1d02:03:04', '2d02:03:04', '10d02:03:04')
start_times = rep(Sys.time(), 3L)
fun(start_time = start_times, duration = durations)
# [1] "2019-06-11 11:02:19 CEST" "2019-06-12 11:02:19 CEST" "2019-06-20 11:02:19 CEST"
chron times
class 以天数和一天的小数部分表示持续时间。我们定义了两个函数,用于将我们的自定义文本格式转换为 times
以及从 times
转换为我们的自定义文本格式。
library(chron)
text2times <- function(x) with(read.table(text = as.character(x), sep = "d", as.is = TRUE),
V1 + times(V2))
times2text <- function(x) paste(as.integer(x), format(x %% 1), sep = "d")
dd <- transform(d, diffdays = text2times(stop) - text2times(start),
difftext = times2text(text2times(stop) - text2times(start)))
给予:
start stop diffdays difftext
1 1d02:03:04 2d02:03:50 1.000532 1d00:00:46
S3 自定义 class 在
期间
这对于您的需要来说可能有些矫枉过正,但我们可以定义一个 S3 class dur
来执行此操作。
as.dur <- function(x, ...) UseMethod("as.dur")
as.dur.character <- function(x, ...) structure(text2times(x), class = c("dur", "times"))
as.dur.factor <- function(x, ...) as.dur(as.character(x))
format.dur <- function(x, ...) times2text(times(x))
# new it's easy
transform(d, diff = as.dur(stop) - as.dur(start))
给予:
start stop diff
1 1d02:03:04 2d02:03:50 1d00:00:46
在 read.table
中使用 dur
我们也可以直接把数据读入dur
class
setAs("character", "dur", function(from) as.dur(from))
# test input - normally read from file but to keep answer self contained use string
Lines <- "start stop
1d02:03:04 2d02:03:50"
# now it's even easier
dd <- read.table(text = Lines, header = TRUE, colClasses = c("dur", "dur"))
transform(dd, diff = stop - start)
## start stop diff
## 1 1d02:03:04 2d02:03:50 1d00:00:46
备注
可重现形式的示例输入:
d <- data.frame(start = "1d02:03:04", stop = "2d02:03:50")
我有一个 CSV 文件,其中包含我想导入到 R 中的通话记录,例如通话时间、被叫号码、通话时长等。
CSV 文件中 'Duration of the call' 字段的格式类似于 1d02:03:04 即 1 天 2 小时 3 分 4 秒。
我可以使用 df.duration = pd.to_timedelta(df.duration)
在 Python Pandas 中轻松地将 Duration 字段转换为 Duration 对象。
转换后,我可以通过将开始时间加上持续时间来获得停止时间。
我正在寻找 R 中相同的等效项以将 1d02:03:04 转换为持续时间对象,以便我可以获得结束时间。
或者,您也可以为此使用 regex
(即使其他解决方案,例如 lubridate
可能更好):
首先创建模式 ^(\d*)d(\d*):?(\d*):?(\d*)$
(可能需要根据您的格式进行调整)以提取持续时间的天数、小时数、分钟数和秒数。然后,您可以根据此信息添加开始时间。
fun = function (start_time, duration) {
# Check start_time
if (!'POSIXct' %in% class(start_time))
stop('Expect "start_time" to be of class "POSIXct"')
# Regex pattern for extraction of days, hours, minutes & seconds
pattern = '^(\d*)d(\d*):?(\d*):?(\d*)$'
# Extract data
days = as.integer(gsub(pattern, '\1', duration))
hours = as.integer(gsub(pattern, '\2', duration))
minutes = as.integer(gsub(pattern, '\3', duration))
seconds = as.integer(gsub(pattern, '\4', duration))
# Maybe add some safety measures just in case e.g. ifelse(is.na(seconds ), 0L, seconds)
# Add (in seconds)
final_time = start_time + seconds + minutes*60 + hours*60*60 + days*60*60*24
return (final_time)
}
这是一个带有向量的小例子
durations = c('1d02:03:04', '2d02:03:04', '10d02:03:04')
start_times = rep(Sys.time(), 3L)
fun(start_time = start_times, duration = durations)
# [1] "2019-06-11 11:02:19 CEST" "2019-06-12 11:02:19 CEST" "2019-06-20 11:02:19 CEST"
chron times
class 以天数和一天的小数部分表示持续时间。我们定义了两个函数,用于将我们的自定义文本格式转换为 times
以及从 times
转换为我们的自定义文本格式。
library(chron)
text2times <- function(x) with(read.table(text = as.character(x), sep = "d", as.is = TRUE),
V1 + times(V2))
times2text <- function(x) paste(as.integer(x), format(x %% 1), sep = "d")
dd <- transform(d, diffdays = text2times(stop) - text2times(start),
difftext = times2text(text2times(stop) - text2times(start)))
给予:
start stop diffdays difftext
1 1d02:03:04 2d02:03:50 1.000532 1d00:00:46
S3 自定义 class 在
期间这对于您的需要来说可能有些矫枉过正,但我们可以定义一个 S3 class dur
来执行此操作。
as.dur <- function(x, ...) UseMethod("as.dur")
as.dur.character <- function(x, ...) structure(text2times(x), class = c("dur", "times"))
as.dur.factor <- function(x, ...) as.dur(as.character(x))
format.dur <- function(x, ...) times2text(times(x))
# new it's easy
transform(d, diff = as.dur(stop) - as.dur(start))
给予:
start stop diff
1 1d02:03:04 2d02:03:50 1d00:00:46
在 read.table
中使用 dur我们也可以直接把数据读入dur
class
setAs("character", "dur", function(from) as.dur(from))
# test input - normally read from file but to keep answer self contained use string
Lines <- "start stop
1d02:03:04 2d02:03:50"
# now it's even easier
dd <- read.table(text = Lines, header = TRUE, colClasses = c("dur", "dur"))
transform(dd, diff = stop - start)
## start stop diff
## 1 1d02:03:04 2d02:03:50 1d00:00:46
备注
可重现形式的示例输入:
d <- data.frame(start = "1d02:03:04", stop = "2d02:03:50")