1

我有一个 600,000 行的 data.table 并在其上执行以下命令:

ranges <- mapply(function(mi, ma) {seq(from=mi, to=ma, by="days")}, mi=Moves$Start, ma=Moves$End)

一段时间后我收到以下错误消息:

Error in seq.int(0, to0 - from, by) : wrong sign in 'by' argument

我用较小的数据集测试了我的代码,这似乎工作正常。这使我认为错误消息是数据集中值的结果。任何人都可以推荐一种有效的方法来跟踪 data.table 中的问题行吗?不用说,手动检查 600k 行有点太多了。

感谢您在 data.table 中查找问题行的建议!

4

2 回答 2

3

显而易见的解决方案是将匿名函数转换为第一类、全名函数,然后您就可以调试该函数了。或者打开恢复选项,然后您可以进入当前堆栈的评估框架并查看引发错误时变量的状态。

myFun <- function(mi, ma) {
  seq(from=mi, to=ma, by="days")
}

为您提供一个命名函数,您可以通过它进行调试

debug(myFun)

或者

debugonce(myFun)

要打开错误恢复,请执行

op <- options(error = recover)

(你可以休息一下:options(op)options(error = stop)

在这种情况下,我怀疑mi大于ma

> myFun(Sys.Date(), Sys.Date()-1)
Error in seq.int(0, to0 - from, by) : wrong sign in 'by' argument

因此您可以更改myFun以查看是否是这种情况:

myFun <- function(mi, ma) {
  if(mi > ma)
    stop("`mi` is > than `ma`")
  seq(from=mi, to=ma, by="days")
}

这样你会得到一个更丰富的错误信息。

如果失败了,我会使用options(error = recover)然后进入与函数对应的评估调用,看看和的值是mi什么ma

于 2013-03-21T18:42:46.877 回答
1

概述

seq.Date()的错误消息试图告诉您Moves$End(即 2017 年 6 月 23 日)的日期发生 Moves$Start(即 2017 年 4 月 17 日)之前。因为seq.Date()假定 in 中的所有日期都from发生在 中的日期之前to,所以该错误会阻止函数继续执行。

要确定发生这种情况的位置,请使用which()来确定哪些日期Moves$End小于Moves$Start。从那里,更新这些日期,使它们发生 Moves$Start.

# load necessary data
Moves <- data.frame( Start = as.Date( x = c("2017-04-17", "2018-03-01", "2019-04-01") )
                     , End = as.Date( x = c("2017-06-23", "2018-02-14", "2018-04-24") )
                     , stringsAsFactors = FALSE )

# try to create a sequence of dates
date.ranges <-
  mapply( FUN = function( mi, ma )
  seq.Date( from = mi
            , to = ma
            , by = "day" )
  , Moves$Start
  , Moves$End
  , SIMPLIFY = FALSE )

# identify the instance
# where the End date occurs
# before the Start date
wrong.end.date <-
  which( Moves$End < Moves$Start )

# view results
wrong.end.date
# [1] 2 3

# correct those End Dates
# so that they occur 
# after the Start date
Moves$End[ wrong.end.date ] <-
  as.Date( x = c("2019-02-14", "2019-04-24") )

# rerun the mapply() function
date.ranges <-
  mapply( FUN = function( mi, ma )
    seq.Date( from = mi
              , to = ma
              , by = "day" )
    , Moves$Start
    , Moves$End
    , SIMPLIFY = FALSE )

# end of script #
于 2018-04-17T16:42:53.803 回答