Как я могу увидеть, какие столбцы я пытался выбрать, когда "выбраны неопределенные столбцы"? - PullRequest
0 голосов
/ 06 июня 2018

Я создаю пакет, который взаимодействует с репозиторием 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, но во время выполнения это не работает так, как я ожидал.Нет ли способа увидеть , какие столбцы не определены?

1 Ответ

0 голосов
/ 07 июня 2018

Вот один из способов, которым вы могли бы сделать это, но мне было бы очень неудобно делать это в пакете R, предназначенном для использования другими.Я не знаю, пометит ли это проверка CMD 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`)) сразу после вызова trace, чтобы функция не отслеживалась даже в случае возникновения ошибок.

...