В чем преимущества использования with()
? В файле справки упоминается, что он оценивает выражение в среде, которую он создает из данных. В чем преимущества этого? Быстрее ли создавать среду и оценивать ее там, а не просто оценивать ее в глобальной среде? Или есть что-то еще, что мне не хватает?
Когда использовать функцию "с" и почему она хороша?
Ответ 1
with
- это оболочка для функций без аргумента data
Есть много функций, которые работают с фреймами данных и принимают аргумент data
, так что вам не нужно повторно вводить имя фрейма данных при каждой ссылке на столбец. lm
, plot.formula
, subset
, transform
- это всего лишь несколько примеров.
with
- это обертка общего назначения, позволяющая использовать любую функцию, как если бы она имела аргумент данных.
Используя набор данных mtcars
, мы могли бы подогнать модель с использованием аргумента данных или без него:
# this is obviously annoying
mod = lm(mtcars$mpg ~ mtcars$cyl + mtcars$disp + mtcars$wt)
# this is nicer
mod = lm(mpg ~ cyl + disp + wt, data = mtcars)
Однако, если (по какой-то странной причине) мы хотели найти mean
в cyl + disp + wt
, возникает проблема, поскольку у mean
нет аргумента данных, как у lm
. Это проблема, которую with
решает:
# without with(), we would be stuck here:
z = mean(mtcars$cyl + mtcars$disp + mtcars$wt)
# using with(), we can clean this up:
z = with(mtcars, mean(cyl + disp + wt))
Обтекание foo()
в with(data, foo(...))
позволяет нам использовать любую функцию foo
, как если бы она имела аргумент data
- то есть мы можем использовать имена столбцов без кавычек, предотвращая повторяющиеся data_name$column_name
или data_name[, "column_name"]
.
Когда использовать with
Используйте with
всякий раз, когда вам нравится интерактивно (консоль R) и в сценариях R, чтобы сохранить ввод текста и сделать ваш код более понятным. Чем чаще вам потребуется повторно вводить имя фрейма данных для одной команды (и чем длиннее имя фрейма данных!), Тем больше выгода от использования with
.
Также обратите внимание, что with
не ограничивается фреймами данных. От ?with
:
Для метода по умолчанию
with
это может быть среда, список, фрейм данных или целое число, как вsys.call
.
Я не часто работаю со средой, но когда я это делаю, я нахожу with
очень удобным.
Когда вам нужны кусочки результата только для одной строки
Как говорит @Rich Scriven в комментариях, with
может быть очень полезным, когда вам нужно использовать результаты чего-то вроде rle
. Если вам нужны результаты только один раз, то его пример with(rle(data), lengths[values > 1])
позволяет использовать результаты rle(data)
анонимно.
Когда следует избегать with
Когда есть аргумент data
Многие функции, имеющие аргумент data
, используют его для более простого синтаксиса при вызове. Большинство функций моделирования (например, lm
) и многие другие (ggplot
!) Многое делают с предоставленным data
. Если вы используете with
вместо аргумента data
, вы ограничите доступные вам функции. Если есть аргумент data
, используйте аргумент data
, а не with
.
Добавление в среду
В моем примере выше результат был присвоен глобальной среде (bar = with(...)
). Чтобы сделать назначение внутри списка/среды/данных, вы можете использовать within
. (В случае data.frames
, transform
также хорош.)
В пакетах
Не используйте with
в пакетах R. В help(subset)
есть предупреждение, которое также может относиться и к with
:
Предупреждение Это удобная функция, предназначенная для интерактивного использования. Для программирования лучше использовать стандартные функции поднабора, такие как
[
, и, в частности, нестандартная оценка подмножества аргументов может иметь непредвиденные последствия.
Если вы создаете пакет R с помощью with
, при его проверке вы, вероятно, получите предупреждения или заметки об использовании переменных без видимой привязки. Это сделает пакет неприемлемым для CRAN.
Альтернативы with
Не используйте attach
Многие (в основном датированные) учебники R используют attach
, чтобы избежать повторного ввода имен фреймов данных, делая столбцы доступными для глобальной среды. attach
широко считается плохой практикой, и ее следует избегать. Одна из основных опасностей присоединения заключается в том, что столбцы данных могут стать не синхронизированными, если они будут изменены индивидуально. with
избегает этой ловушки, потому что она вызывается по одному выражению за раз. В Qaru есть много вопросов, когда новые пользователи следуют старому учебнику и сталкиваются с проблемами из-за attach
. Простое решение всегда не использовать attach
.
Использование with
все время кажется слишком повторяющимся
Если вы делаете много шагов манипулирования данными, вы можете обнаружить, что начинаете каждую строку кода с with(my_data, ...
. Вы можете подумать, что это повторение почти так же плохо, как и не использование with
. Оба пакета data.table
и dplyr
предлагают эффективную обработку данных с неповторяющимся синтаксисом. Я бы посоветовал вам научиться использовать один из них. Оба имеют отличную документацию.
Ответ 2
Я использую его, когда не хочу набирать dataframe$
. Например
with(mtcars, plot(wt, qsec))
а не
plot(mtcars$wt, mtcars$qsec)
Первая просматривает wt
и qsec
в mtcars
data.frame. Конечно,
plot(qsec~wt, mtcars)
более подходит для сюжетных или других функций, которые принимают аргумент data=
.