查找在R Lubridate中无法解析的日期

xwbd5t1u  于 2023-10-13  发布在  其他
关注(0)|答案(7)|浏览(126)

作为一个R新手,我正在努力调试隐藏的R错误。我有一个包含150 k行的csv,我将其加载到一个名为“date”的 Dataframe 中。然后我使用lubridate将这个字符列转换为datetime,希望找到最小/最大日期。

dates <- csv[c('datetime')]
  dates$datetime <- ymd_hms(dates$datetime)

运行此代码时,我收到以下错误消息:

Warning message:
3 failed to parse.

我接受这一点,因为CSV可能有一些janky日期在那里和下一次运行:

min(dates$datetime) 
max(dates$datetime)

这两个返回NA,我假设这是来自仍然存储在 Dataframe 中的几个破碎的日期。我四处寻找快速修复方法,甚至试图构建一个foreach循环来识别问题日期,但没有成功。有什么简单的方法来识别3个破碎的日期?

example date format: 2015-06-17 17:10:16 +0000
8zzbczxx

8zzbczxx1#

以上评论归功于LawyerR和Stibu:
1.我首先对原始的CSV列进行排序,并执行head()& tail(),以查找哪3个日期引起了问题
1.或者which(is.na(dates$datetime))是一个简单的一行程序也找到了答案。

x9ybnkn6

x9ybnkn62#

当Lubridate试图解析由于夏令时而 * 不存在 * 的日期时,将抛出该错误。
举例来说:

library(lubridate)
mydate <- strptime('2020-03-08 02:30:00', format = "%Y-%m-%d %H:%M:%S")
ymd_hms(mydate, tz = "America/Denver")

[1] NA
Warning message:
 1 failed to parse.

我的数据来自一个不知道夏令时的非智能传感器,所以不可能(但格式正确)的日期出现在我的时间序列中。

vshtjzan

vshtjzan3#

下面是一个简单的函数,它可以解决一般的问题:

parse_ymd = function(x){
  d=lubridate::ymd(x, quiet=TRUE)
  errors = x[!is.na(x) & is.na(d)]
  if(length(errors)>0){
    cli::cli_warn("Failed to parse some dates: {.val {errors}}")
  }
  d
}

x = c("2014/20/21", "2014/01/01", NA, "2014/01/02", "foobar")
my_date = lubridate::ymd(x)
#> Warning: 2 failed to parse.
my_date = parse_ymd(x)
#> Warning: Failed to parse some dates: "2014/20/21" and "foobar"

创建于2022-09-29带有reprex v2.0.2
当然,可以用任何你想要的东西替换ymd()

58wvjzkj

58wvjzkj4#

如果知道lubridate失败位置的索引很有用,可以使用带有stopifnot()的for循环并打印每个成功的解析。
做一些日期,在一个随机的位置抛出一个错误。

library(lubridate)
set.seed(1)
my_dates<-as.character(sample(seq(as.Date('1900/01/01'), 
as.Date('2000/01/01'), by="day"), 1000))
my_dates[sample(1:length(my_dates), 1)]<-"purpleElephant"

现在使用for循环并使用stopifnot()打印每个成功的解析。

for(i in 1:length(my_dates)){
   print(i)
   stopifnot(!is.na(ymd(my_dates[i])))
}
svdrlsy4

svdrlsy45#

为了提供更一般的答案,首先过滤掉NA s,然后尝试解析,最后只过滤NA s。这将向您展示失败。例如:

dates2 <- dates[!is.na(dates2$datetime)]
dates2$datetime <- ymd_hms(dates2$datetime)

Warning message:
 3 failed to parse.

dates2[is.na(dates2$datetime)]
fhg3lkii

fhg3lkii6#

使用截断参数。日期-时间数据中最常见的不规则类型是由于时间戳的舍入或不可用而导致的截断。
因此,尝试truncated = 1,然后可能会上升到truncated = 3:

dates <- csv[c('datetime')]
  dates$datetime <- ymd_hms(dates$datetime, truncated = 1)
thtygnil

thtygnil7#

ludridate::ymd_hms()在尝试解析时间戳字符串时,需要一定数量的字符(通常为19个)。有时,午夜的时间戳只呈现为日期部分,这意味着字符串只有10个字符。还有其他原因,例如简单的数据错误可能导致非标准的字符串长度,但基于NA的操作不会找到这些。
要查看字符串长度是否存在异常,可以使用
table(nchar(dates$datetime))
如果发现带有问题字符串的条目,可以使用
which(nchar(dates$datetime) != 19)

相关问题