обзор в R и работа с «с»

В R есть много ситуаций, когда кажется, что with используется, чтобы помочь вам написать более короткий код; однако это маскирует существующие символы, такие как локальные переменные и параметры функций. Есть ли способ ссылаться на них, не переименовывая их, чтобы они не конфликтовали с вашими данными?

Например, в этом фрейме у меня есть столбец state;

df <- data.frame(
  label=c("a", "b", "c"),
  state=c("off","on","off"))

Я могу написать функцию фильтрации с параметром .state, и фильтр работает;

instateWorks <- function(.state) {
  subset(df, df$state == .state)
}

# correct - 1 observation for "b"
onWorks <- instateWorks("on") 

но если я даю своей функции разумное имя параметра, возникает проблема, и символ state, похоже, относится к столбцу фрейма данных;

instateFails <- function(state) {
  subset(df, df$state == state)
}

# fails - all 3 observations
onFails <- instateFails("on") 

Есть ли способ уточнить, что state должен означать параметр, чтобы скрипт работал должным образом?


Изменить - чтобы уточнить, почему "with" и "eval" являются проблемой, с которой я борюсь, рассмотрите этот код;

df <- data.frame(
  label=c("a", "b", "c"),
  state=c("off","on","off"))

with(df, state == "on")
# FALSE TRUE FALSE

state <- on
with(df, state == state)
# TRUE TRUE TRUE

В последнем операторе with я ищу способ выразить «скажите мне, в каких строках переменная 'state' в DF имеет то же значение, что и переменная 'state', определенная в строке выше.

Без этой возможности я не могу написать функцию с параметром, который называется так же, как имя столбца.


person Steve Cooper    schedule 20.04.2016    source источник
comment
используйте это вместо подмножества: instateFails ‹- function(state) df[df$state == state,]   -  person chinsoon12    schedule 20.04.2016
comment
From help(subset) - Предупреждение Это удобная функция, предназначенная для интерактивного использования. Для программирования лучше использовать стандартные функции подмножества, такие как [, и, в частности, нестандартное вычисление подмножества аргументов может иметь непредвиденные последствия.   -  person Rich Scriven    schedule 20.04.2016
comment
Я использую подмножество только потому, что оно иллюстрирует проблему с «с». Та же проблема возникает, скажем, в dplyr, где я не могу сказать filter(df, state == state). Это общая проблема с передачей выражений функциям, которые eval находятся в среде, отличной от вызывающей функции.   -  person Steve Cooper    schedule 20.04.2016
comment
В dplyr вы должны использовать filter_() внутри функций (обратите внимание на _). Для этой цели пакет был написан со стандартной версией. Если у вас есть вопрос о with(), отредактируйте, потому что with() не используется в subset().   -  person Rich Scriven    schedule 20.04.2016
comment
И «подмножество», и пакеты в Hadleyverse будут иметь нестандартные сюрпризы при оценке.   -  person IRTFM    schedule 20.04.2016
comment
@HaddE.Nuff обновил вопрос! Благодарность   -  person Steve Cooper    schedule 20.04.2016
comment
Вам нужно будет использовать что-то вроде with(df, state == get("state", globalenv())), чтобы пойти и получить state из глобальной среды. Но, как вы можете видеть, мы победили цель более короткого кода, так как теперь мы можем просто сделать df$state == state. Кроме того, он может стать волосатым, используя get()   -  person Rich Scriven    schedule 20.04.2016
comment
@HaddE.Nuff - вызов environment() на самом деле дает мне то, что я ищу. Я могу сделать ; instateFails <- function(state) { args <- environment(); subset(df, state == args$state) } для дифференциации -- создайте переменную с именем args (или как-то так), которая позволит мне обращаться к переменным в вызывающей функции из выражения фильтра. Должно работать везде, и это однострочный обходной путь...   -  person Steve Cooper    schedule 20.04.2016


Ответы (1)


Благодаря @HaddE.Nuff я придумал это;

instateFails <- function(state) {
  args <- environment()
  subset(df, state == args$state)
}

захватить текущую среду, прежде чем сделать вызов, что дает вам возможность обратиться ко всем локальным жителям в вызывающей функции. Затем обратитесь к переменной среды внутри выражения фильтра.

person Steve Cooper    schedule 20.04.2016