【问题标题】:How can I see which columns I tried to select when "undefined columns selected"?当“选择未定义的列”时,如何查看我尝试选择的列?
【发布时间】:2018-06-06 18:32:22
【问题描述】:

我正在构建一个与 git 存储库接口并与 R 函数的历史版本一起使用的包。问题是有时,这些旧函数期望输入 data.frame 有它没有的列。这些列不影响功能,但它们曾经在数据中,并且在这些旧函数中被硬编码。所以当然,我得到一个“未定义的列选择”错误。

我想使用 tryCatch 查看缺少哪些列并将它们作为虚拟对象添加到我的 data.frame 中。例如,

old_fn <- function(x) {
  print(x[, "c"])
  return(x)
}

df <- data.frame(a = c(1,2,3), b = c(3,4,5))
result <- 0
while(result == 0) {
  result <- tryCatch(
    old_fn(df),
    error = function(cond) {
      if (grepl("undefined columns selected", cond, fixed = T)) {
        missing_cols <- # ????
        for (col in missing_cols) {
          df[[eval(col)]] <- NA
        }
        return(0)
      } else {
      return(1)
      }
    }
  )
}

我尝试过调用traceback() 并从那里获取missing_cols,但这在运行时似乎并没有像我期望的那样工作。有没有办法查看哪些列未定义?

【问题讨论】:

  • 你的预期输出是什么?
  • 嗯,从上面的代码中,我希望看到NA 打印到控制台,因为这就是old_fn 的成功运行。当然,这是一个人为的例子。查看修改
  • 我能想到的任何可以解析错误消息的解决方案都非常脆弱(比您正在与之交互的旧功能更脆弱)
  • 啊,所以您认为在我找到这些列时对我自己进行硬编码可能更明智?喜欢,for (col in c("whatever", "old", "columns")) { if (! col %in% colnames(fn_data)) { fn_data[[eval)col)]] &lt;- NA }}

标签: r dataframe try-catch


【解决方案1】:

这是您可以做到这一点的一种方法, 但我会觉得在一个打算被其他人使用的 R 包中做这件事很不舒服。 我不知道 R 的 CMD 检查是否会标记它。

您可以通过在控制台中输入`[.data.frame` 来查看用于子集数据帧的默认函数。 在那里你可以看到正式的论点和正文。 你会看到默认的形式是function (x, i, j, drop = if (missing(i)) TRUE else length(cols) == 1)。 然后,您可以使用 trace 注入将在函数评估开始时评估的表达式:

create_missing_cols <- function(x, j) {
  missing_cols <- setdiff(j, colnames(x))
  if (length(missing_cols) > 0L) {
    for (column in missing_cols) {
      x[[column]] <- NA
    }
  }
  # return
  x
}

trace(`[.data.frame`, 
      print = FALSE, 
      tracer = quote(x <- create_missing_cols(x, j)))

df <- data.frame(a = 1:2)
df[, c("a", "b", "c")]
  a  b  c
1 1 NA NA
2 2 NA NA

untrace(`[.data.frame`)

这假定您将仅在 j 是字符向量时使用它。

编辑:如果你最终使用这个, 绝对考虑在调用trace 之后立即使用on.exit(untrace(`[.data.frame`)), 这样即使发生错误,该功能也不会被跟踪。

【讨论】:

  • 天啊。是的,我明白你不想在包装中使用它的观点。这将是只有我组织内的人会使用的东西,但我同意这有点不舒服。我试试看
猜你喜欢
  • 2015-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多