代码之家  ›  专栏  ›  技术社区  ›  data princess

当“未定义列已选定”时,如何查看我试图选择哪些列?

  •  0
  • data princess  · 技术社区  · 7 年前

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

    我想用 tryCatch 查看缺少哪些列并将它们作为虚拟对象添加到my 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 回复  |  直到 7 年前
        1
  •  1
  •   Alexis    7 年前

    你有一个办法, 但我会觉得很不舒服,在一个R包,这意味着被其他人使用。 我不知道R的命令检查是否会标记它。

    您可以通过键入 `[.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`)) 就在打电话给 追踪 , 这样即使出现错误,函数也不会被跟踪。