当选择"未定义的列时,如何查看我尝试选择哪些列"?

时间:2018-06-06 18:32:22

标签: r dataframe try-catch

我正在构建一个与git存储库连接的包,并使用R函数的历史版本。麻烦的是,有时候,这些旧函数期望输入data.frame具有它没有的列。这些列不会影响功能,但它们曾经存在于数据中,并且在这些旧功能中进行了硬编码。当然,我选择了#34;未定义的列"错误。

我想使用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,但这似乎在运行期间不像我期望的那样工作。有没有办法看到哪些列未定义?

1 个答案:

答案 0 :(得分:1)

这是你可以做到这一点的一种方式, 但是我觉得在R包装中做这件事是非常不舒服的。 我不知道R&C的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是字符向量时才使用它。

编辑:如果你最终使用这个, 一定要考虑在调用on.exit(untrace(`[.data.frame`))后立即使用trace, 这样即使发生错误,该功能也不受限制。