Rainer M Krug
2015-Apr-09 12:39 UTC
[R] Convert numerical value into function which returns numerical value
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 -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 494 bytes Desc: not available URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20150409/6b756ac3/attachment.bin>
William Dunlap
2015-Apr-09 14:57 UTC
[R] Convert numerical value into function which returns numerical value
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]]
Bert Gunter
2015-Apr-10 14:28 UTC
[R] Convert numerical value into function which returns numerical value
"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
Hadley Wickham
2015-Apr-10 14:33 UTC
[R] Convert numerical value into function which returns numerical value
> 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).For this question in particular, I'd recommend starting at http://adv-r.had.co.nz/Functional-programming.html Hadley -- http://had.co.nz/
David Barron
2015-Apr-10 15:49 UTC
[R] Convert numerical value into function which returns numerical value
I'd have a look at Hadley Wickham's online Advanced R here: http://adv-r.had.co.nz/. It has a section on Functional progamming that deals with this kind of thing. David On 10 April 2015 at 15:28, Bert Gunter <gunter.berton at gene.com> wrote:> "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 > > ______________________________________________ > 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.