Mac与PC上R代码运行的报错/警告差异及解决方法咨询
跨平台R代码执行差异问题:Mac报错与PC警告的原因及解决方法
问题详情
运行同一段日期转换代码时,Mac端触发致命报错导致程序终止,PC端仅弹出警告,不影响后续分析流程。
执行代码
convert.dates <- function(data, columns, format="%Y-%m-%d %H:%M:%S") { if (length(columns) == 1) { posdates <- data.frame(strptime(data[, columns], format)) names(posdates) <- columns } else posdates <- as.data.frame(apply(data[, columns], 2, strptime, format)) data <- data[, -match(columns, names(data))] data.frame(data, posdates) } recdat$datetime <- as.character(strptime(recdat$datetime, "%Y:%m:%d %H:%M:%S")) recdat <- convert.dates(recdat, "datetime")
报错/警告信息
- Mac端报错:
Error in strptime(data[, columns], format) : input string is too long
- PC端警告:
row names were found from a short variable and were discarded
测试数据结构
structure(list(placeID = c("SHPP9", "SHPP9", "MAPP4", "MAPP4", "MAPP4", "MAPP4", "HAPP15", "HAPP15", "HAPP15", "DEPP2"), fileID = c("IMG_0086_grid_compass.JPG", "IMG_0089_grid_compass.JPG", "IMG_0146_grid_compass.JPG", "IMG_0149_grid_compass.JPG", "IMG_0152_grid_compass.JPG", "IMG_0155_grid_compass.JPG", "IMG_2671_grid_compass.JPG", "IMG_2673_grid_compass.JPG", "IMG_2676_grid_compass.JPG", "IMG_0008_grid_compass.JPG" ), datetime = c("2019:06:01 02:59:22", "2019:06:01 02:59:23", "2019:06:06 00:45:32", "2019:06:06 00:45:33", "2019:06:06 00:45:49", "2019:06:06 00:45:50", "2019:06:07 23:05:46", "2019:06:07 23:05:47", "2019:06:07 23:05:48", "2019:06:10 22:29:47"), time = c(0.782634725415124, 0.78270744746729, 31.6146031824166, 31.6146759044688, 31.6158394573035, 31.6159121793556, 43.7456595925075, 43.7457323145597, 43.7458050366119, 62.438208603419), species = c("Civet", "Civet", "Civet", "Civet", "Civet", "Civet", "Civet", "Civet", "Civet", "Civet"), absangle = c(0.233516621633944, 0.22839855680029, 0.0168248958289925, 0.112940296923411, 0.00228507404113898, 0.0993839863232428, 0.221094165650959, 0.180608750801481, 0.12502377891255, 0.269755048548634), distance = c(6.25093914350113, 5.90579526441211, 3.35416246724451, 3.5986715069128, 3.74569894202013, 3.2687423704556, 8.63358410851277, 9.12459363127179, 9.03891669576689, 3.70247933884298 )), row.names = c(NA, -10L), class = c("tbl_df", "tbl", "data.frame" ))
原因分析
- 日期格式不匹配:
convert.dates函数默认使用%Y-%m-%d %H:%M:%S格式,但原始datetime列的格式是%Y:%m:%d %H:%M:%S(年与月之间是冒号而非横杠)。Mac系统的strptime函数对格式不匹配的处理更严格,直接抛出致命错误;Windows系统则相对宽松,仅弹出警告并尝试兼容转换。 - 冗余类型转换:代码中先将
datetime转为strptime对象再转回字符型,这一步完全多余,反而可能引入格式混乱,放大跨平台差异。 - 数据框行名处理差异:Mac与Windows对
data.frame构造时的行名逻辑不同,PC端的警告由此产生,但Mac端的格式错误触发了优先级更高的致命报错。
解决方法
方法1:修正格式参数并移除冗余转换
直接在调用convert.dates时指定正确的日期格式,同时删除不必要的类型转换步骤:
convert.dates <- function(data, columns, format="%Y-%m-%d %H:%M:%S") { if (length(columns) == 1) { posdates <- data.frame(strptime(data[, columns], format)) names(posdates) <- columns } else posdates <- as.data.frame(apply(data[, columns], 2, strptime, format)) data <- data[, -match(columns, names(data))] data.frame(data, posdates) } # 直接传入正确格式调用函数,移除冗余转换 recdat <- convert.dates(recdat, "datetime", format="%Y:%m:%d %H:%M:%S")
方法2:使用lubridate包(推荐)
lubridate包的日期解析函数跨平台一致性更强,无需复杂格式指定,代码更简洁:
library(lubridate) # 直接解析datetime列,指定格式匹配原始数据 recdat$datetime <- ymd_hms(recdat$datetime, format = "%Y:%m:%d %H:%M:%S")
方法3:优化原函数的行名处理
若坚持使用原函数,可在构造数据框时显式禁用行名,同时确保格式正确:
convert.dates <- function(data, columns, format="%Y-%m-%d %H:%M:%S") { if (length(columns) == 1) { posdates <- data.frame(strptime(data[, columns], format), row.names = NULL) names(posdates) <- columns } else posdates <- as.data.frame(apply(data[, columns], 2, strptime, format), row.names = NULL) data <- data[, -match(columns, names(data)), drop = FALSE] data.frame(data, posdates, row.names = NULL) } recdat <- convert.dates(recdat, "datetime", format="%Y:%m:%d %H:%M:%S")
内容的提问来源于stack exchange,提问作者Jamie McKaughan
相关产品推荐
相关产品推荐

