Нестандартная оценка, путаница в продвинутой R книге

Итак, в продвинутой книге Хэдли "R" есть пример проблемы с использованием замены, вот выдержка из кода:

subset2 <- function(x, condition) {
condition_call <- substitute(condition)
r <- eval(condition_call, x, parent.frame())
x[r, ]
}

scramble <- function(x) x[sample(nrow(x)), ]

subscramble <- function(x, condition) {
 scramble(subset2(x, condition))
}


subscramble(sample_df, a >= 4)
# Error in eval(expr, envir, enclos) : object 'a' not found
traceback()
#> 5: eval(expr, envir, enclos)
#> 4: eval(condition_call, x, parent.frame()) at #3
#> 3: subset2(x, condition) at #1
#> 2: scramble(subset2(x, condition)) at #2
#> 1: subscramble(sample_df, a >= 4)

Вы видите, в чем проблема? condition_call содержит условие выражения. Поэтому, когда мы вычисляем условие condition_call, оно также оценивает условие, которое имеет значение a >= 4. Однако это невозможно вычислить, поскольку в родительской среде нет объекта с именем a. Но, если бы они были установлены в глобальной среде, могут произойти еще более запутанные вещи:

Есть несколько вещей, которые смущают меня в вышеприведенном абзаце из книги.

  1. Предложение "condition_call содержит выражение условие". Символ "условие" используется в качестве формального аргумента в функции subset2, а также используется в качестве реального аргумента в схватке (subset2(x, условие)). Я думаю, он ссылался на этот реальный / вызывающий аргумент "условие", верно?

  2. Как обещание, состояние в определении subcramble лениво оценивается? Почему это не оценивается при вызове: scramble(subset2(x,condition))

Другими словами, как узнать, оценивается ли обещание или нет, глядя на код? Например, если я правильно понимаю, если я изменю код на следующий:

scramble(subset2(x,(condition))) 

теперь условие вынуждено оценивать. Какие здесь правила?

  1. Когда Хэдли говорит, что "когда мы оцениваем условие_колл, оно также оценивает условие", что такое "это"? Он имел в виду, что "eval" вызвал какую-то внутреннюю или вторичную оценку, которая пытается разрешить обещание "условие"? Где это происходит? т.е. какую среду пытается использовать R, чтобы выяснить, каково значение "условия"?

  2. Таким образом, ошибка "объект не найден" не из-за "x" или "parent.frame()" в вызове ниже, а скорее где-то еще?? Я полностью сбит с толку.

    r <- eval (condition_call, x, parent.frame ())

1 ответ

Я не могу комментировать, поэтому я опубликую это как ответ. Все будет просто перефразировать:

Нестандартная оценка из другой функции в R

По сути, в среде вызова sample_df функция будет искать "условие" вместо "a>=4". Поскольку он не может найти это, он перемещается вверх и затем находит условие в вызывающей среде; среда выполнения субскрамбла (это потому, что subset2(x, условие) является обещанием, созданным в этой среде), где она находит>=4.

Теперь ему нужно найти a, но мы уже покинули среду данных sample_df, поэтому он ищет ее в глобальной среде, что приводит к странным результатам, если в глобальной среде определено a.

Другие вопросы по тегам