Russ Abbott
2011-May-07 06:38 UTC
[R] Convenience-at-the-expense-of-clarity (was: quantmod's addTA plotting functions)
Thanks, Writing plot(addTA()) worked fine. I find myself with such mixed feelings about R. After finding that addTA worked fine at the command line but not in a function, I puzzled for a long time about what kind of virtual machine structure could possibly account for that. I couldn't think of any. It turns out that this isn't due to an R virtual machine structure. The reason addTA adds its function to the plot when run from the command line is that Jeff went to the trouble to make it do that. addTA is not intended to add a plot to an existing chart. Yet the problem I ran into is that the addTA documentation doesn't say that. Instead it says, "addTA takes a series of values, either in a form coercible to xts or of the same length as the charted series has rows, and displays the results in either a new TA sub-window, or over/underlayed on the main price chart." I took that to mean that when I called addTA (from anywhere) a plot would be added to an existing plot. But that's not true. On the contrary, as I now understand addTA, it's function is to return an object that when passed to plot() will then be added to an existing chart. It is not intended to add the new plot to an existing chart by itself. That interpretation makes sense given the documentation under Value. It reads "addTA will invisibly return an S4 object of class chobTA. If this function is called interactively, the chobTA object will be evaluated and added to the current chart." (By the way, there is no documentation for chobTA--at least none that I could find.) The implication here is that addTA is not supposed to have the side effect of adding something to an exiting chart. It is only because Jeff went to the added trouble to make addTA add its plot to an existing chart when called interactively that it does so. This raises a larger question about R style. I frequently seem to run into conveniences that are programmed into R functions. On the one hand, it's (at least superficially) nice to have those conveniences. On the other hand, it makes it much more difficult to develop a clear intuition about how the language and its functions work. I continually find myself confused by these inconveniences because I generally assume they are part of the core functionality of the function. When they aren't it's very confusing. My preferences would be not to have those extra conveniences. I'd rather have to type a few extra keystrokes and keep my intuition about how a function works clean and simple than have a muddy intuition and save a few keystrokes. In this case, for example, if one wanted an addTA that actually added something to a plot, why not create a new function called something like plot.addTA. Then addTA would work the same way both in a function and interactively and people like me (i.e., newcomers to the library) wouldn't get confused. I want to be clear that this isn't directed at Jeff. What Jeff did was consistent with what seems to me to be the R culture. It's convenience-at-the-expense-of-clarity that I'm finding difficult to get used to. I find this causes problems for me when for one reason or another I have the arguments to a function wrong. I'm used to languages like Java that tell you when the arguments are wrong. In R it's so often the case that the arguments might be right (because there are so many convenient ways of passing things to functions) that the compiler can't tell you when the arguments are wrong. On a number of occasions it's taken far more time than it should to find errors of that sort. The convenience wasn't worth the wasted time. That's my rant for today. *-- Russ * On Thu, May 5, 2011 at 10:13 AM, P Ehlers <ehlers@ucalgary.ca> wrote:> Russ, > > All you have to do is replace > > > addTA(GSPC.EMA.3, on = 1, col = "#0000ff") > > with > > plot(addTA(GSPC.EMA.3, on = 1, col = "#0000ff")) > > etc. > > I can sympathize with the documentation frustration, but I think > that much of the documentation in R and in many R packages is > actually very good. I get much more frustrated with the attempts > at 'non-technical' explanations I find in other software. It > does take a bit of getting used to always looking at the Value > section and, if in doubt, checking some of the See Alsos, but > it's worth it. I don't know quantmod very well, but even a > cursory look at the pdf file shows that the docs are quite > good. > > As Jeff points out, good documentation is not easy. More good > examples are always better, but that's mighty time-consuming. > > Peter Ehlers > > > On 2011-05-05 10:42, Russ Abbott wrote: > >> Thanks. You're right. I didn't see that. I read the ?addTA help page, >> which (annoyingly) didn't mention that feature, but I didn't read the >> ?TA page. (That page was mentioned as a see also, but not as a must see.) >> >> I don't know what it means to wrap these calls in a plot call. I tried >> to put the addTA calls into a function and call that function from the >> higher level function, but that didn't work either. Would you tell me >> what it means to wrap these calls in a plot call. >> >> Thanks >> /-- Russ / >> >> P.S. Pardon my irritation, but I continually find that many of the help >> files assume one already knows the information one is looking for. If >> you don't know it, the help files are not very helpful. This is a good >> example. In fact, it's two good examples. I didn't know that I had to >> look at another page, and I (still) don't know what it means to wrap >> plot calls in another plot call. >> >> >> On Thu, May 5, 2011 at 3:39 AM, P Ehlers <ehlers@ucalgary.ca >> <mailto:ehlers@ucalgary.ca>> wrote: >> >> On 2011-05-05 0:47, Russ Abbott wrote: >> >> Hi, >> >> I'm having trouble with quantmod's addTA plotting functions. >> They seem to >> work fine when run from the command line. But when run inside a >> function, >> only the last one run is visible. Here's an example. >> >> >> test.addTA<- function(from = "2010-06-01") { >> getSymbols("^GSPC", from = from) >> GSPC.close<- GSPC[,"GSPC.Close"] >> GSPC.EMA.3<- EMA(GSPC.close, n=3, ratio=NULL) >> GSPC.EMA.10<- EMA(GSPC.close, n=10, ratio=NULL) >> chartSeries(GSPC.close, theme=chartTheme('white'), >> up.col="black", >> dn.col="black") >> addTA(GSPC.EMA.3, on = 1, col = "#0000ff") >> addTA(GSPC.EMA.10, on = 1, col = "#ff0000") >> # browser() >> } >> >> >> When I run this, GSPC.close always appears. But only GSPC.EMA10 >> appears on >> the plot along with it. If I switch the order of the addTA calls, >> only GSPC.EMA3 appears. If I uncomment the call to browser() >> neither appears >> when the browser() interrupt occurs. I can then draw both >> GSPC.EMA.3 and >> GSPC.EMA10 manually, and let the function terminate. All >> intended plots are >> visible after the function terminates. So it isn't as if one >> wipes out the >> other. This shows that it's possible to get all three lines on >> the plot, but >> I can't figure out how to do it without manual intervention. Any >> suggestions >> are appreciated. >> >> >> Perhaps you didn't see this NOTE on the ?TA help page: >> >> "Calling any of the above methods from within a function >> or script will generally require them to be wrapped in a >> plot call as they rely on the context of the call to >> initiate the actual charting addition." >> >> Peter Ehlers >> >> >> Thanks. >> >> *-- Russ * >> >> [[alternative HTML version deleted]] >> >> ______________________________________________ >> R-help@r-project.org <mailto:R-help@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. >> >> >>[[alternative HTML version deleted]]
Joshua Wiley
2011-May-07 07:04 UTC
[R] Convenience-at-the-expense-of-clarity (was: quantmod's addTA plotting functions)
On Fri, May 6, 2011 at 11:38 PM, Russ Abbott <russ.abbott at gmail.com> wrote: <snip>> That's my rant for today.If you use Emacs, I recommend: M-x doctor RET Cheers, Josh P.S. Many package authors would love help writing documentation (it is often on their to-do lists somewhere slogged behind desired functionality, bug patches, and their day jobs that pay the bills). If some documentation does not meet your standards for clarity/thoroughness, write it up and send it over.> > *-- Russ *-- Joshua Wiley Ph.D. Student, Health Psychology University of California, Los Angeles http://www.joshuawiley.com/
Jeff Newmiller
2011-May-07 07:24 UTC
[R] Convenience-at-the-expense-of-clarity (was: quantmod's addTA plotting functions)
There is a simple principle to remember: interactively, R evaluates expressions and prints them. If the expression returns a simple object like a numeric vector, it prints in the obvious way. When the result is more complex, like an lm object, it uses a custom print function and you see a "report". When the object is a grid graphics object, it appears in the plot window. If the code is in a function then it hasn't been handed over to the interpreter yet, so it will only be printed if you return it or print it yourself. Once you get used to it, you will probably stop explicitly printing/plotting inside your functions and instead just build objects that will be printed when they are returned to the interpreter. --------------------------------------------------------------------------- Jeff Newmiller The ..... ..... Go Live... DCN:<jdnewmil@dcn.davis.ca.us> Basics: ##.#. ##.#. Live Go... Live: OO#.. Dead: OO#.. Playing Research Engineer (Solar/Batteries O.O#. #.O#. with /Software/Embedded Controllers) .OO#. .OO#. rocks...1k --------------------------------------------------------------------------- Sent from my phone. Please excuse my brevity. Russ Abbott <russ.abbott@gmail.com> wrote: Thanks, Writing plot(addTA()) worked fine. I find myself with such mixed feelings about R. After finding that addTA worked fine at the command line but not in a function, I puzzled for a long time about what kind of virtual machine structure could possibly account for that. I couldn't think of any. It turns out that this isn't due to an R virtual machine structure. The reason addTA adds its function to the plot when run from the command line is that Jeff went to the trouble to make it do that. addTA is not intended to add a plot to an existing chart. Yet the problem I ran into is that the addTA documentation doesn't say that. Instead it says, "addTA takes a series of values, either in a form coercible to xts or of the same length as the charted series has rows, and displays the results in either a new TA sub-window, or over/underlayed on the main price chart." I took that to mean that when I called addTA (from anywhere) a plot would be added to an existing plot. But that's no t true. On the contrary, as I now understand addTA, it's function is to return an object that when passed to plot() will then be added to an existing chart. It is not intended to add the new plot to an existing chart by itself. That interpretation makes sense given the documentation under Value. It reads "addTA will invisibly return an S4 object of class chobTA. If this function is called interactively, the chobTA object will be evaluated and added to the current chart." (By the way, there is no documentation for chobTA--at least none that I could find.) The implication here is that addTA is not supposed to have the side effect of adding something to an exiting chart. It is only because Jeff went to the added trouble to make addTA add its plot to an existing chart when called interactively that it does so. This raises a larger question about R style. I frequently seem to run into conveniences that are programmed into R functions. On the one hand, it's (at least superficially) nice to have those conveniences. On the other hand, it makes it much more difficult to develop a clear intuition about how the language and its functions work. I continually find myself confused by these inconveniences because I generally assume they are part of the core functionality of the function. When they aren't it's very confusing. My preferences would be not to have those extra conveniences. I'd rather have to type a few extra keystrokes and keep my intuition about how a function works clean and simple than have a muddy intuition and save a few keystrokes. In this case, for example, if one wanted an addTA that actually added something to a plot, why not create a new function called something like plot.addTA. Then addTA would work the same way both in a function and interactively and people like me (i.e., newcomers to the library) wouldn't get confused. I want to be clear that this isn't directed at Jeff. What Jeff did was consistent with what seems to me to be the R culture. It's convenience-at-the-expense-of-clarity that I'm finding difficult to get used to. I find this causes problems for me when for one reason or another I have the arguments to a function wrong. I'm used to languages like Java that tell you when the arguments are wrong. In R it's so often the case that the arguments might be right (because there are so many convenient ways of passing things to functions) that the compiler can't tell you when the arguments are wrong. On a number of occasions it's taken far more time than it should to find errors of that sort. The convenience wasn't worth the wasted time. That's my rant for today. *-- Russ * On Thu, May 5, 2011 at 10:13 AM, P Ehlers <ehlers@ucalgary.ca> wrote: > Russ, > > All you have to do is replace > > > addTA(GSPC.EMA.3, on = 1, col = "#0000ff") > > with > > plot(addTA(GSPC.EMA.3, on = 1, col = "#0000ff")) > > etc. > > I can sympathize with the documentation frustration, but I think > that much of the documentation in R and in ma ny R packages is > actually very good. I get much more frustrated with the attempts > at 'non-technical' explanations I find in other software. It > does take a bit of getting used to always looking at the Value > section and, if in doubt, checking some of the See Alsos, but > it's worth it. I don't know quantmod very well, but even a > cursory look at the pdf file shows that the docs are quite > good. > > As Jeff points out, good documentation is not easy. More good > examples are always better, but that's mighty time-consuming. > > Peter Ehlers > > > On 2011-05-05 10:42, Russ Abbott wrote: > >> Thanks. You're right. I didn't see that. I read the ?addTA help page, >> which (annoyingly) didn't mention that feature, but I didn't read the >> ?TA page. (That page was mentioned as a see also, but not as a must see.) >> >> I don't know what it means to wrap these calls in a plot call. I tried >> to put the addTA calls into a function and call that function from the >> higher level func tion, but that didn't work either. Would you tell me >> what it means to wrap these calls in a plot call. >> >> Thanks >> /-- Russ / >> >> P.S. Pardon my irritation, but I continually find that many of the help >> files assume one already knows the information one is looking for. If >> you don't know it, the help files are not very helpful. This is a good >> example. In fact, it's two good examples. I didn't know that I had to >> look at another page, and I (still) don't know what it means to wrap >> plot calls in another plot call. >> >> >> On Thu, May 5, 2011 at 3:39 AM, P Ehlers <ehlers@ucalgary.ca >> <mailto:ehlers@ucalgary.ca>> wrote: >> >> On 2011-05-05 0:47, Russ Abbott wrote: >> >> Hi, >> >> I'm having trouble with quantmod's addTA plotting functions. >> They seem to >> work fine when run from the command line. But when run inside a >> function, >> only the last one run is visible. Here's an example. >> >> >> test.addTA<- function(from = "2010-06-01") { >> getSymbols("^GSPC ", from = from) >> GSPC.close<- GSPC[,"GSPC.Close"] >> GSPC.EMA.3<- EMA(GSPC.close, n=3, ratio=NULL) >> GSPC.EMA.10<- EMA(GSPC.close, n=10, ratio=NULL) >> chartSeries(GSPC.close, theme=chartTheme('white'), >> up.col="black", >> dn.col="black") >> addTA(GSPC.EMA.3, on = 1, col = "#0000ff") >> addTA(GSPC.EMA.10, on = 1, col = "#ff0000") >> # browser() >> } >> >> >> When I run this, GSPC.close always appears. But only GSPC.EMA10 >> appears on >> the plot along with it. If I switch the order of the addTA calls, >> only GSPC.EMA3 appears. If I uncomment the call to browser() >> neither appears >> when the browser() interrupt occurs. I can then draw both >> GSPC.EMA.3 and >> GSPC.EMA10 manually, and let the function terminate. All >> intended plots are >> visible after the function terminates. So it isn't as if one >> wipes out the >> other. This shows that it's possible to get all three lines on >> the plot, but >> I can't figure out how to do it without manual intervention. Any >> sugges tions>> are appreciated. >> >> >> Perhaps you didn't see this NOTE on the ?TA help page: >> >> "Calling any of the above methods from within a function >> or script will generally require them to be wrapped in a >> plot call as they rely on the context of the call to >> initiate the actual charting addition." >> >> Peter Ehlers >> >> >> Thanks. >> >> *-- Russ * >> >> [[alternative HTML version deleted]] >> >>_____________________________________________ >> R-help@r-project.org <mailto:R-help@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. >> >> >> [[alternative HTML version deleted]]_____________________________________________R-help@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. [[alternative HTML version deleted]]