[R] Convert numerical value into function which returns numerical value
Bert Gunter
gunter.berton at gene.com
Fri Apr 10 16:28:06 CEST 2015
"Is there a good resource for these advanced programming techniques in R?"
1. I would not consider this "advanced." I would consider "computing
on the language" techniques and manipulation of environments to be
advanced, for example.
2. But anyway, there are tons of R Programming resources. John
Chambers's books and even the venerable "S Programming" book of
Venables and Ripley might be worth checking; Hadley Wickham has
written quite a few web resources that are being developed into a book
(or have already been) -- you can probably find these by following
links from the R STudio website or checking his repositories at
Github. But there are many more both on the Web and in print, and you
would do better to search on your own to find something that suits
your learning style and needs rather than relying on my fairly
uninformed opinion (as I do not teach R and therefore have made no
effort to be current with the resources).
Cheers,
Bert
Bert Gunter
Genentech Nonclinical Biostatistics
(650) 467-7374
"Data is not information. Information is not knowledge. And knowledge
is certainly not wisdom."
Clifford Stoll
On Fri, Apr 10, 2015 at 1:27 AM, Rainer M Krug <Rainer at krugs.de> wrote:
> Bert Gunter <gunter.berton at gene.com> writes:
>
>> 1. An important point that Bill uses but did not explicitly state is
>> that R is (essentially) a functional programming language, which means
>> among other things that functions can return functions as values.
>
> Yup - that is essential here. A function is also only an object in R,
> like characters or numeric values.
>
>>
>> 2. As a perhaps slightly amusing variant of Bill's construct that
>> illustrates this is the function below whose value is a function that
>> either returns a constant determined when it is defined or its
>> argument when called if no constant was given to it on definition:
>>
>> fconv <- function(arg=NULL){
>> function(z)if(is.null(arg))z else arg
>> }
>
> You know, this is exactly what I want to do: I have a function, which
> takes either a numerical value or a function (from PAI) as the argument
> dep. So I have to check if the dep is a function or a value. At the
> moment, I am using is.function(), and when dep is not a function,
> convert it to a function which returns dep. If it is a function, I can
> leave it as it is. I could also replace, in your code, the is.null()
> with is.function() and do effectively the same here (some edits
> required).
>
> Very neat indeed.
>
> And a perfect way of making functions very versatile. IU really have to
> look closer into these things.
>
> Is there a good resource for these advanced programming techniques in R?
>
> Thanks,
>
> Rainer
>
>
>>> x <- 5
>>> g1 <- fconv(x) ## g1 will always return 5
>>> g1()
>> [1] 5
>>> g1(1)
>> [1] 5
>>
>>> x <- 2
>>> g1(x) ## Still uses the "x" in its defining environment
>> [1] 5
>>
>> ## But ...
>>> g2 <- fconv() ## No constant given to it in its definition
>>> g2(x)
>> [1] 2
>>> g2(1)
>> [1] 1
>>> g2()
>> Error in g2() : argument "z" is missing, with no default
>>
>> Cheers,
>> Bert
>>
>> Bert Gunter
>> Genentech Nonclinical Biostatistics
>> (650) 467-7374
>>
>> "Data is not information. Information is not knowledge. And knowledge
>> is certainly not wisdom."
>> Clifford Stoll
>>
>>
>>
>>
>> On Thu, Apr 9, 2015 at 7:57 AM, William Dunlap <wdunlap at tibco.com> wrote:
>>> You can make such functions by using the fact that a function
>>> (really, a 'closure') always has access to the environment in
>>> which the function was created. E.g.
>>> makeConstantFunction <- function(constant) {
>>> force(constant) # evaluate the argument now
>>> function(PAI) {
>>> constant
>>> }
>>> }
>>> f17 <- makeConstantFunction(17)
>>> flog17 <- makeConstantFunction(log(17))
>>> f17(111)
>>> # [1] 17
>>> flog17(111)
>>> # [1] 2.833213
>>>
>>> If you print f17 and flog17 they will look the same, except for
>>> their environments and you have to inspect those to see why
>>> they act differently.
>>>
>>> ls.str(environment(f17))
>>> # constant : num 17
>>> ls.str(environment(flog17))
>>> # constant : num 2.83
>>>
>>> If you really want the functions to look different you can use
>>> substittute or bquote, but that is also a bit mysterious (you need the
>>> eval()
>>> their outputs):
>>> g17 <- eval(substitute(function(PAI)x, list(x=17)))
>>> h17 <- eval(bquote(function(PAI).(x), list(x=17)))
>>> g17(10)
>>> [1] 17
>>> h17(10:1)
>>> [1] 17
>>>
>>>
>>>
>>>
>>> Bill Dunlap
>>> TIBCO Software
>>> wdunlap tibco.com
>>>
>>> On Thu, Apr 9, 2015 at 5:39 AM, Rainer M Krug <Rainer at krugs.de> wrote:
>>>
>>>>
>>>> Hi
>>>>
>>>> I want convert, in a function, an argument from a numerical value to a
>>>> function which returns this value.:
>>>>
>>>> My Code:
>>>>
>>>> --8<---------------cut here---------------start------------->8---
>>>> dep <- 13
>>>> dep <- function() {dep}
>>>> dep
>>>> --8<---------------cut here---------------end--------------->8---
>>>>
>>>> This is what I get:
>>>> #+RESULTS:
>>>> ,----
>>>> | function(PAI) { dep }
>>>> `----
>>>>
>>>> This is what I want
>>>> ,----
>>>> | function(PAI) { 13 }
>>>> `----
>>>>
>>>> I thought about using eval(dep), but this gives me the effectively the
>>>> same.
>>>>
>>>> Is it possible to achieve what I want? I somehow have the feeling this
>>>> is not that easily possible, as the code in the function definition is
>>>> only evaluated when the function is evaluated.
>>>>
>>>> I could obviously do something like
>>>>
>>>> --8<---------------cut here---------------start------------->8---
>>>> dep <- 13
>>>> depVal <- dep
>>>> dep <- function() {depVal}
>>>> dep()
>>>> --8<---------------cut here---------------end--------------->8---
>>>>
>>>> But is there a better solution?
>>>>
>>>> Thanks,
>>>>
>>>> Rainer
>>>>
>>>> --
>>>> Rainer M. Krug, PhD (Conservation Ecology, SUN), MSc (Conservation
>>>> Biology, UCT), Dipl. Phys. (Germany)
>>>>
>>>> Centre of Excellence for Invasion Biology
>>>> Stellenbosch University
>>>> South Africa
>>>>
>>>> Tel : +33 - (0)9 53 10 27 44
>>>> Cell: +33 - (0)6 85 62 59 98
>>>> Fax : +33 - (0)9 58 10 27 44
>>>>
>>>> Fax (D): +49 - (0)3 21 21 25 22 44
>>>>
>>>> email: Rainer at krugs.de
>>>>
>>>> Skype: RMkrug
>>>>
>>>> PGP: 0x0F52F982
>>>>
>>>> ______________________________________________
>>>> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see
>>>> 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]]
>>>
>>> ______________________________________________
>>> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see
>>> 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.
>
> --
> Rainer M. Krug, PhD (Conservation Ecology, SUN), MSc (Conservation Biology, UCT), Dipl. Phys. (Germany)
>
> Centre of Excellence for Invasion Biology
> Stellenbosch University
> South Africa
>
> Tel : +33 - (0)9 53 10 27 44
> Cell: +33 - (0)6 85 62 59 98
> Fax : +33 - (0)9 58 10 27 44
>
> Fax (D): +49 - (0)3 21 21 25 22 44
>
> email: Rainer at krugs.de
>
> Skype: RMkrug
>
> PGP: 0x0F52F982
More information about the R-help
mailing list