将hh:mm:ss格式的duration.video变量重编码为分类变量遇问题
解决hh:mm:ss格式时间转分类变量的问题
你的核心问题在于直接用car::recode对字符型时间字符串做区间匹配——这种写法只适用于数值型变量,字符型时间的字典序逻辑和实际时长的区间判断完全不匹配,再加上代码里的区间写法存在语法错误,才导致所有值被错误归类。转data.table::ITime后没解决,是因为你没利用ITime底层存储为秒数的特性做数值判断。
下面是两种可靠的解决方法:
方法1:转成总秒数后用case_when分类
先把hh:mm:ss转成可计算的总秒数,再用逻辑判断划分区间:
# 定义函数:将hh:mm:ss转为总秒数 time_to_sec <- function(x) { parts <- strsplit(x, ":")[[1]] as.numeric(parts[1]) * 3600 + as.numeric(parts[2]) * 60 + as.numeric(parts[3]) } # 生成秒数列 video$duration_sec <- sapply(video$Duration.video, time_to_sec) # 用dplyr的case_when生成分类 library(dplyr) video$duration_category <- case_when( duration_sec >= 1 & duration_sec <= 299 ~ "少于5分钟", # 对应00:00:01到00:04:59 duration_sec >= 300 & duration_sec <= 1800 ~ "5到30分钟之间", # 对应00:05:00到00:30:00 duration_sec >= 1801 & duration_sec <= 7199 ~ "30分钟到2小时之间", # 对应00:30:01到01:59:59 duration_sec >= 7200 ~ "2小时及以上", # 对应02:00:00及更久 TRUE ~ NA_character_ # 处理异常值,比如空值或无效格式 ) # 转为因子变量 video$duration_category <- as.factor(video$duration_category)
方法2:用data.table::ITime直接做数值判断
ITime本质是存储为秒数的整数,直接用它做区间匹配即可:
library(data.table) # 转为ITime格式 video$Duration.video <- as.ITime(video$Duration.video) # 生成分类 video$duration_category <- case_when( Duration.video >= as.ITime("00:00:01") & Duration.video <= as.ITime("00:04:59") ~ "少于5分钟", Duration.video >= as.ITime("00:05:00") & Duration.video <= as.ITime("00:30:00") ~ "5到30分钟之间", Duration.video >= as.ITime("00:30:01") & Duration.video <= as.ITime("01:59:59") ~ "30分钟到2小时之间", Duration.video >= as.ITime("02:00:00") ~ "2小时及以上", TRUE ~ NA_character_ ) video$duration_category <- as.factor(video$duration_category)
原代码失效的原因
car::recode的"a:b"区间写法仅针对数值型变量,字符型变量下该写法要么语法错误,要么只能做精确匹配,无法识别时间区间。即使你转成了ITime,若仍用car::recode的字符匹配逻辑,也无法利用其数值属性完成区间判断,自然得不到正确结果。
内容的提问来源于stack exchange,提问作者Nacim Ouahes
相关产品推荐
相关产品推荐

