问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

关于R中读取日期数据出错的解决办法

发布网友 发布时间:2022-11-25 09:49

我来回答

1个回答

热心网友 时间:2023-10-09 07:44

    R从excel文件中读取日期数据经常出现错误(如, 日期数据读入之后变成整数,或者整数与标准的日期格式共存等),这种情况大多是数据读入R之前数据类型保存有误(有些日期类型存储成了整数类型,或者整数与标准的日期类型数据共存) ,数据读入R之后,无法使用R中常用的日期处理函数(如lubridate的ymd()等函数)将数据转换为标准的日期函数(yyyy-mm-dd)。

    遇到这种情况,我们可以通过colClasses或col_types来指定读入的数据列类型为日期类型('date'), 此时如果数据不是标准的日期类型(如yyyy-mm-dd)数据读入依然会出错。此时,可以指定数据列类型为文本类型('character'或'text'),此时数据读入不会出错,但是读入后需要对数据进行转换(整数形式的日期数据,如'41250', 需要转换为标准的日期类型数据:yyyy-mm-dd)。

    日期与整数之间是可以转换的。 通常,日期与 1899年12月31日(或1970年1月1日-Unix时间)相差的天数即为相应日期对应的整数, 碰到日期中有'42110', '12334',  '2018-12-12'形式存在的数据时, 需要判断日期数据是整数形式还是标准的日期格式。

下面写了一个简单的函数,来处理日期数据中既有整数形式的日期数据(如'41120'),又有标准日期类型的数据的情况:

str2num <- function(data){

  return (as.numeric(as.character(data)))

}

change_date <- function(date_str){

  ##转为标准的年月日日期

  date_str <- str_replace_all(date_str, "‘|’|“|”|“|”", '')

  date_str <- str_replace_all(date_str, '年|月', '-')

  date_str <- str_replace_all(date_str, '日', ' ')

  date_str <- str_replace_all(date_str, '^\\s+|\\s+$', '')

  ##如果只有一个小数点,保留整数就行了

  if (length(str_extract_all(date_str, '\\.')[[1]]) == 1 &&

      !is.na(as.numeric(as.character(date_str)))){

    date_str <- str_replace(date_str, '\\.\\d+$', '')

  }

  ##空白字符后面的内容删除

  date_str <- str_split(date_str, '\\s+', simplify = T)[, 1]

  ##标准的日期1

  ##yyyy-mm-dd, yyyy.mm.dd, yyyy/mm/dd, yyyy\mm\dd

  tmp_bool1 <- str_detect(date_str, paste('\\d{4}[-./\\\\]\\d{1,2}[-./\\\\]\\d{1,2}', 

                                '\\d{8}', sep = '|'))

  ##标准日期2

  ##mm-dd-yyy, mm.dd.yyyy, mm/dd/yyyy, mm\dd\yyyy

  tmp_bool2 <- str_detect(date_str, '\\d{1,2}[-./\\\\]\\d{1,2}[-./\\\\]\\d{4}')

  indexs <- 1:length(date_str)

  ##标准日期1,下标,年月日

  norm_index1 <- which(tmp_bool1 == T)

  ##标准日期2下标, 月日年

  norm_index2 <- which(tmp_bool2 == T)

  ##非标准日期,转换成了数字格式的日期

  int_index <- indexs[!indexs %in% c(norm_index1, norm_index2)]

  tmp_int <- date_str[int_index]

  tmp_int <- round(str2num(tmp_int), 0)

  date_int <- as.character(ymd('1900-1-1') + ddays(tmp_int - 2))

  date_str[c(norm_index1, norm_index2)] <- str_replace_all(date_str[c(norm_index1,                                        norm_index2)], '[/.\\\\]', '-')

  ##norm index1

  date_str[norm_index1] <- as.character(ymd(date_str[norm_index1]))

  ##norm index2

  date_str[norm_index2] <- as.character(mdy(date_str[norm_index2]))

  ##int index

  date_str[int_index] <- date_int

  return(date_str)

}

调用上面的函数后,数据都转化为了'yyyy-mm-dd'形式的字符串数据

需要调用lubridate包中的ymd()函数进一步将字符串数据转换为日期数据。

ps:不同来源的日期数据转换要注意开始计算天数的日期是1899-12-31还是1970-1-1。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
梦见老婆光脚踩谷子 王者荣耀国服中,不论进入游戏还是没开始游戏,所有玩家发送的任何消息... 我的滴滴开空调活动怎么没了 为什么腾讯视频显示还是要流量看 没有联通中国结标志 电脑不能装win7买电脑时他们说只能装win10系统不能装win7 英雄联盟手游 手机lol游戏盒子现在叫什么? 英雄联盟手机盒子看不了比赛记录 手游英雄联盟视频在哪里看手机英雄联盟盒子在哪看我游戏中录的视频 英雄联盟盒子看视频只有声音没有画面,不是网速的问题,也不是电脑卡,是... 为什么英雄联盟盒子没发看视频 优鸡良品获取数据出错 苹果手机核酸检测app获取数据错误怎么办 您好,我是今年要毕业的学生,想问您一下宁波中远您了解吗?待遇福利怎么样? 输卵管两侧通而不畅,上午在医院理疗,晚上再用粗盐热敷可以吗 深圳市比亚迪泥头车提前报废政策? 比亚迪电动泥头车与开沃的区别 比亚迪后尾10t是哪款车 向大家详细咨询一下青石板多少钱一平方? 花呗到底有什么用? 多长时间去一次角质啊 光敏感电阻最大可以用多少v 最小是多少v 0分贝就是没有声音? 格力电器股目标价2021 用Nero7刻光盘,如何设置可以以后再次刻录剩余空间? 刑事法律考试卷的题目都有哪些 《穷爸爸富爸爸》系列书籍里边的唐纳德是现在当选的美国总统吗? 十万左右安全性能好的,省油自动挡的车,哪个好,市区开为主? 预算在13-15万之间,想买自动挡省油的SUV,哪些值得推荐? 枣树上有小虫子,怎么办呀? 欧美资本主义国家的发展过程给我们留下了什么启示 怎么做李子果醋 爱丽舍启动机止推圈怎么拆 内径是40mm,外径是60mm,厚度是6mm的止推轴承是什么型号 谢谢! 哪位大神知道一个小饰品的名字,, 遇见的歌词? 柴油机曲轴连接为何不能用键连接 求山东省各地市小商品批发市场名字,不要济南临沂的 回转窑容易出现哪些工艺生产故障? 采源宝如何多添加几个供应商 上海大观园的最佳旅游季节 去上海大观园的交通路线 马克西姆多大年纪 小学清明节日记 50字有没有 怎样联系客服注销 可以打电话给腾讯客服注销吗? 怎么注销 客户咨询蚂蚁公馆的销售情况? 看江的小户型公寓哪个比较好? 中国移动以前0月租卡资费 求大神、帮忙设计一个新足球队的队徽,在线等,急急急 ,谢谢