enclosing with() in a function

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

enclosing with() in a function

thmsfuller066@gmail.com
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

______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: enclosing with() in a function

Michael Weylandt
Hi Tom,

What exactly is this function supposed to do? Your immediate problem is that
you are passing it a string "x" and asking for a mean of the string "x"
(hence complaints that it's not numeric) but I'm a little confused as to
what this is supposed to do when it works.

If you just want the mean of the list element named "x", this should do:

mean(data[["x"]])

If more generally you need to set up an environment, perhaps attach will
work -- but if  you intend to write a function, why not just subset the list
as needed?

mean_on_element2 <- function(data,elem_name) {
    r = mean(data[[elem_name]])
    return(r)
}

Now you can access list elements by their index or by a string containing
the name.

Hope this helps,

Michael Weylandt

On Mon, Aug 8, 2011 at 6:12 PM, [hidden email] <
[hidden email]> 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
>
> ______________________________________________
> [hidden email] 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.
>

        [[alternative HTML version deleted]]

______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: enclosing with() in a function

djmuseR
In reply to this post by thmsfuller066@gmail.com
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')

# (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, [hidden email]
<[hidden email]> 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
>
> ______________________________________________
> [hidden email] 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.
>

______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: enclosing with() in a function

Peter Dalgaard-2

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



>
> # (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, [hidden email]
> <[hidden email]> 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
>>
>> ______________________________________________
>> [hidden email] 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.
>>
>
> ______________________________________________
> [hidden email] 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: [hidden email]  Priv: [hidden email]
"Døden skal tape!" --- Nordahl Grieg

______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: enclosing with() in a function

thmsfuller066@gmail.com
On Mon, Aug 8, 2011 at 6:08 PM, peter dalgaard <[hidden email]> 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, [hidden email]
>> <[hidden email]> 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
>>>
>>> ______________________________________________
>>> [hidden email] 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.
>>>
>>
>> ______________________________________________
>> [hidden email] 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: [hidden email]  Priv: [hidden email]
> "Døden skal tape!" --- Nordahl Grieg
>
>
>
>
>
>
>
>



--
Tom

______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: enclosing with() in a function

thmsfuller066@gmail.com
In reply to this post by Peter Dalgaard-2
On Mon, Aug 8, 2011 at 6:08 PM, peter dalgaard <[hidden email]> 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)

I'm trying to understand 'substitute', is there a way to visualize the
parsed tree returned by 'substitute'?

> substitute(mean(x))
mean(x)
> str(substitute(mean(x)))
 language mean(x)


> 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
>
>
>
>>
>> # (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, [hidden email]
>> <[hidden email]> 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
>>>
>>> ______________________________________________
>>> [hidden email] 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.
>>>
>>
>> ______________________________________________
>> [hidden email] 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: [hidden email]  Priv: [hidden email]
> "Døden skal tape!" --- Nordahl Grieg
>
>
>
>
>
>
>
>



--
Tom

______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: enclosing with() in a function

Duncan Murdoch-2
On 11-08-08 9:58 PM, [hidden email] wrote:

> On Mon, Aug 8, 2011 at 6:08 PM, peter dalgaard<[hidden email]>  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)
>
> I'm trying to understand 'substitute', is there a way to visualize the
> parsed tree returned by 'substitute'?

as.list() turns the top level of the tree into a list.  You could
recursively apply that.  I don't know if there's an existing function to
do so, but it's not hard to write one:

expand <- function(e) {
        if (is.name(e) || !is.language(e)) return(e)
        lapply(as.list(e), expand)
}

Duncan Murdoch

>
>> substitute(mean(x))
> mean(x)
>> str(substitute(mean(x)))
>   language mean(x)
>
>
>> 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
>>
>>
>>
>>>
>>> # (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, [hidden email]
>>> <[hidden email]>  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
>>>>
>>>> ______________________________________________
>>>> [hidden email] 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.
>>>>
>>>
>>> ______________________________________________
>>> [hidden email] 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: [hidden email]  Priv: [hidden email]
>> "Døden skal tape!" --- Nordahl Grieg
>>
>>
>>
>>
>>
>>
>>
>>
>
>
>

______________________________________________
[hidden email] 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.