【问题标题】:Locating the cause of data-sourced errors within ddply在 ddply 中定位数据源错误的原因
【发布时间】:2013-07-12 21:45:29
【问题描述】:

我喜欢使用plyr,但有时底层数据会引发我无法定位的错误。

例如,我创建了一个求和函数,如果x == 8

df <- data.frame(x = rep(1:10,3), y = runif(30))

ddply(df,
      .(x),
      function (z) { 
        if(z$x[1] == 8) {
          stop("There's an error somewhere.")
        }
        return(sum(z$y))
        })

假装我不知道是什么导致了错误,有什么方法可以报告是哪些数据行导致了错误?

【问题讨论】:

  • 你试过使用 traceback() 吗?
  • 啊,这看起来很有前途@Jdbaba。我得到了结果:8: stop("There's an error somewhere.") at #5。我如何解释#5 的含义?
  • 这不是一个很好的例子,因为您的 df$y 现在全是字符;无论如何,只需使用trytryCatch
  • @eddi,对,我刚刚注意到并改回来了。有没有办法将整个function (z) 包裹在trytryCatch 中?现在,由于实际用例很长,我必须将每个操作都包含在函数中。 (老实说,我还没有找到一种方法,使用 tryCatch 来让它报告导致问题的数据。也许我已经脑残了。)

标签: r error-handling plyr


【解决方案1】:

这里是一个使用tryCatch的例子:

set.seed(1)
df <- data.frame(x = rep(1:10,3), y = runif(30))

f = function (z) { 
        if(z$x[1] == 8) {
          stop("There's an error somewhere.")
        }
        return(sum(z$y))
    }

ddply(df, .(x), function(z) {
         tryCatch(f(z), error = function(e) {
              print("offending block is"); print(z)
         })
     })

#[1] "offending block is"
#  x         y
#1 8 0.6607978
#2 8 0.9919061
#3 8 0.3823880
#Error in list_to_dataframe(res, attr(.data, "split_labels")) : 
#  Results must be all atomic, or all data frames

【讨论】:

  • 完美;谢谢。我在使用 tryCatch 时犯了一些小错误,这个例子把它们都清除了。
【解决方案2】:

当您使用ddply 时,您可以在函数中使用data.frame df 的整个子集作为变量z。所以,你可以在那里做任何你想做的事情。

z[z$x==8,]

例如,会给你有问题的行。如果您想知道哪个子集引发了错误,您可以执行以下操作:

if (z$x[1] ==8) {
  stop(paste('There is an error in the', unique(z$x), 'subset of df'))
}

否则,您必须更清楚地解释您要查找的内容。包括一个错误的工作示例数据集和一个关于您想知道的信息的示例将有很长的路要走……就目前而言,我只是在猜测!

【讨论】:

  • 啊,假装你不能触及任何代码中引发错误的东西(stop 函数),因为在我的实际用例中,我不是那个引发错误的人。我希望有一个触发器,上面写着'如果抛出错误,print(unique(z$x)),但我目前无法让它工作。例如,if (length(warnings()) &gt; 0) { print(first(z$x))} 没有帮助,因为该函数不会传递错误并到达打印值的那一点。
  • 我不知道你对print(...)你写的东西是什么意思,@贾斯汀。更新后的示例是否更有意义:由于我不再是控制错误的人,我不确定如何找到导致错误的数据。
  • 由于您还没有提供有关您正在做什么的任何信息,我无法提供帮助,但您正在寻找tryCatch。更具体地说,tryCatch(sum(x$y), error=function(e) e) 之类的东西会在不停止的情况下捕获错误。
  • 嗯。我实际上在做的是一个非常长的函数,它刚刚开始用新数据抛出错误,所以它的重现性不是很好。有没有办法让 tryCatch 返回导致错误的数据?我对抑制错误然后查找导致错误的数据不太感兴趣。不过,感谢您迄今为止的所有帮助,@Justin。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-22
相关资源
最近更新 更多