[R] enclosing with() in a function

thmsfuller066 at gmail.com thmsfuller066 at gmail.com
Tue Aug 9 03:47:23 CEST 2011


On Mon, Aug 8, 2011 at 6:08 PM, peter dalgaard <pdalgd at gmail.com> wrote:
>
> On Aug 9, 2011, at 00:29 , Dennis Murphy wrote:
>
>> Hi:
>>
>> Here are a couple of ways; there may well be better ones.
>>
>> # (1)  Use the get() function:
>> mean_on_element=function(data, elem_name) {
>>   with(data, mean(get(elem_name)))
>> }
>> mean_on_element(data, 'x')
>
> I suspect this goes belly-up if there's a column data$elem_name, though.
>
> Given than with() is essentially evalq() which in turn is eval(quote(...),...), the obvious way to achieve the desired effect would be to omit quoting the argument and do
>
> eval(substitute(mean(elem_name)), data)
>
> or, to avoid unexpected variable capture:
>
> mean_on_element <- function(data, elem_name)
>   eval(substitute(mean(elem_name)), data, parent.frame())
>
> mean_on_element(airquality, Day)
>
> Or rather: this allows variable capture of the same kind that with() allows:
>
>> mean_on_element(airquality, X)
> [1] 0.575
>> with(airquality, mean(X))
> [1] 0.575

I guess the conclusion is that there is extra work to refactor the
code that use 'with' into a function. Am I correct?

For example, I have the following code that use 'with'.

data=list(
    x1=1
    , x2=1
    , x3=1
    , x4=1
    , x4=1
    , x6=1
    ) #could be a very long list.
with(data, x1+x3+x6) # could specify an arbitrary number of elements to sum.

However, if I want to refactor it into a function, I basically have to
rewrite the whole statement (based the replies in this thread, it
doesn't seems that there is not a way to not to change the code too
much during refactoring). Therefore, in order to make the code
refactorable, it is better not use 'with'. (Although 'with' is more
useful in interactive environment when it is desirable to have to
press less keystrokes.) Is my conclusion correct?

my_sum=function(data, name_list) {
  sum(unlist(data[name_list]))
}

my_sum(data, c('x1', 'x3', 'x6'))


>>
>> # (2) Lose 'with' and use subscripting instead:
>> mean_on_element=function(data, elem_name) {
>>   mean(data[[elem_name]])
>> }
>> mean_on_element(data, 'x')
>>
>> Since 'x' is quoted in the function call, you need to use code that
>> can convert the string 'x' to extracting the data object with name x.
>>
>> HTH,
>> Dennis
>>
>> On Mon, Aug 8, 2011 at 3:12 PM, thmsfuller066 at gmail.com
>> <thmsfuller066 at gmail.com> wrote:
>>> Hi All,
>>>
>>> I want to enclose with() in a function mean_on_element. Obviously, it
>>> is not working. The problem is how to specify the element name with a
>>> function body. Does anybody have any suggestion? Thanks!
>>>
>>>> data=list(x=1:10)
>>>> with(data, mean(x))
>>> [1] 5.5
>>>>
>>>> mean_on_element=function(data, elem_name) {
>>> +   with(data, mean(elem_name))
>>> + }
>>>> mean_on_element(data, 'x')
>>> [1] NA
>>> Warning message:
>>> In mean.default(elem_name) :
>>>  argument is not numeric or logical: returning NA
>>>
>>>
>>> --
>>> Tom
>>>
>>> ______________________________________________
>>> R-help at r-project.org mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-help
>>> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
>>> and provide commented, minimal, self-contained, reproducible code.
>>>
>>
>> ______________________________________________
>> R-help at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
>> and provide commented, minimal, self-contained, reproducible code.
>
> --
> Peter Dalgaard, Professor,
> Center for Statistics, Copenhagen Business School
> Solbjerg Plads 3, 2000 Frederiksberg, Denmark
> Phone: (+45)38153501
> Email: pd.mes at cbs.dk  Priv: PDalgd at gmail.com
> "Døden skal tape!" --- Nordahl Grieg
>
>
>
>
>
>
>
>



-- 
Tom



More information about the R-help mailing list