从 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

我们也可以直接把数据读入durclass

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")