Whilst it is a good idea to improve the posting guide, it seems to me that it would be useful to have a function along the lines of bug.report(), to help a potential questioner make sure they have done their homework and have the relevant information to put into a post to R-help.

Even those of us who know what ought to go into a post can sometimes forget to check something obvious - I recently got caught out by not checking an error was reproducible in the patched version for example.

So I have written a help.request() function (see below), which
- prompts the user to check the relevant resources, stopping and opening the relevant url where necessary - checks their R version is up-to-date (in a rather messy way - please suggest improvements!) - prompts them to prepare appropriate example code and test it in a fresh R session
- prompts them to give a meaningful subject line
- automatically adds system info to the post (as in bug.report)
- sends the message for them (ensuring a fresh thread is started)

Is this an idea worth taking further? I would be happy to make improvements as suggested and write a help file if so.

Heather

------------------------------------------------------------

help.request <- function (subject = "",
                          ccaddress = Sys.getenv("USER"),
                          method = getOption("mailer"),
                          address = "[EMAIL PROTECTED]",
                          file = "R.help.request")
{
    no <- function(answer) answer == "n"
    yes <- function(answer) answer == "y"
    go <- function(url) {
cat("Please do this first - the site has been loaded in your web browser\n")
        browseURL(url)
    }
    cat("Checklist:\n")
    post <- readline("Have you read the posting guide? (y/n) ")
    if (no(post)) return(go("http://www.r-project.org/posting-guide.html";))
    FAQ <- readline("Have you checked the FAQ? (y/n) ")
    if (no(FAQ)) return(go("http://cran.r-project.org/faqs.html";))
    intro <- readline("Have you checked An Introduction to R? (y/n) ")
if (no(intro)) return(go("http://cran.r-project.org/doc/manuals/R-intro.html";)) NEWS <- readline("Have you checked the NEWS of the latest development release? (y/n) ")
    if (no(NEWS)) return(go("https://svn.r-project.org/R/trunk/NEWS";))
    rsitesearch <- readline("Have you looked on RSiteSearch? (y/n) ")
    if (no(rsitesearch)) {
cat("Please do this first - the site has been loaded in your web browser\n")
        return(RSiteSearch(subject))
    }
    inf <- sessionInfo()
    if ("otherPkgs" %in% names(inf)){
other <- readline("You have packages other than the base packages loaded.", "\nIf your query relates to one of these, have you ",
                          "checked any corresponding books/manuals \nand ",
"considered contacting the package maintainer? (y/n/NA) ")
        if(no(other)) return("Please do this first.")
    }

    man <- url("http://cran.r-project.org/manuals.html";)
ver <- scan(man, what = character(0), sep = "\n", skip = 13, nlines = 1, quiet = TRUE)
    major <- as.numeric(substr(ver, start = 18, stop = 18))
    minor <- as.numeric(substr(ver, start = 20, stop = 22))
    if (major < as.numeric(R.Version()$major) ||
        minor < as.numeric(R.Version()$major)) {
update <- readline("Your R version is out-of-date, would you like to update now? (y/n) ")
        if (yes(update)) {
            return(go(getOption("repos")))
        }
    }
    ## To get long prompt!
    cat("Have you written example code that is\n",
        "- minimal\n - reproducible\n - self-contained\n - commented",
        "\nusing data that is either\n",
        "- constructed by the code\n - loaded by data()\n",
        "- reproduced using dump(\"mydata\", file = \"\")\n")
code <- readline(paste("have you checked this code in a fresh R session", "\n(invoking R with the --vanilla option if possible)", "\nand is this code copied to the clipboard? (y/n) "))
    if (no(code))
        return(cat("\nIf your query is not directly related to code",
               "(e.g. a general query \nabout R's capabilities),",
               "email [EMAIL PROTECTED] directly. ",
               "\nOtherwise prepare some example code first.\n"))
change <- readline(paste("Would you like to change your subject line:\n", subject, "\nto something more meaningful? (y/n) "))
    if (yes(change))
        subject <- readline("Enter subject: \n")

    methods <- c("mailx", "gnudoit", "none", "ess")
    method <- if (is.null(method))
        "none"
    else methods[pmatch(method, methods)]
body <- paste("\\n<<Write your query here, using your example code to illustrate>>",
                  "\\n<<End with your name and affiliation>>\\n\\n\\n\\n",
                  "--please do not edit the information below--\\n\\n",
"Version:\\n ", paste(names(R.version), R.version, sep = " = ", collapse = "\\n "), if (nzchar(Sys.getenv("R_GUI_APP_VERSION"))) paste("\\n\\nGUI:\\n R-GUI ", Sys.getenv("R_GUI_APP_VERSION"),
                        " (", Sys.getenv("R_GUI_APP_REVISION"), ")",
                        sep = "")
else "", "\\n\\n", "Locale:\\n", Sys.getlocale(), "\\n\\n",
                  "Search Path:\\n ", paste(search(), collapse = ", "),
                  "\\n", sep = "", collapse = "")
    if (method == "gnudoit") {
        cmd <- paste("gnudoit -q '", "(mail nil \"", address,
"\")", "(insert \"", body, "\")", "(search-backward \"Subject:\")",
                     "(end-of-line)'", sep = "")
        system(cmd)
    }
    else if (method == "none") {
disclaimer <- paste("# Your mailer is set to \"none\" (default on Windows),\n",
            "# hence we cannot send the help request directly from R.\n",
            "# Please copy the help request (after finishing it) to\n",
            "# your favorite email program and send it to\n#\n",
"# ", address, "\n#\n", "######################################################\n",
            "\n\n", sep = "")
        cat(disclaimer, file = file)
        body <- gsub("\\\\n", "\n", body)
        cat(body, file = file, append = TRUE)
        cat("Please edit the help request.\n")
        system(paste(getOption("editor"), file))
        cat("The unsent help request can be found in file", file,
            "\n")
    }
    else if (method == "mailx") {
        if (missing(subject))
            stop("'subject' missing")
        body <- gsub("\\\\n", "\n", body)
        cat(body, file = file, append = FALSE)
        cat("Please edit the help request.\n")
        system(paste(getOption("editor"), file))
        if (is.character(ccaddress) && nzchar(ccaddress)) {
            cmdargs <- paste("-s '", subject, "' -c", ccaddress,
                address, "<", file, "2>/dev/null")
        }
        else cmdargs <- paste("-s '", subject, "'", address,
            "<", file, "2>/dev/null")
        status <- 1
        cat("Submit the help request? ")
        answer <- readline()
        answer <- grep("y", answer, ignore.case = TRUE)
        if (length(answer) > 0) {
            cat("Sending email ...\n")
            status <- system(paste("mailx", cmdargs))
            if (status > 0)
                status <- system(paste("Mail", cmdargs))
            if (status > 0)
                status <- system(paste("/usr/ucb/mail", cmdargs))
            if (status == 0)
                unlink(file)
            else {
                cat("Sending email failed!\n")
                cat("The unsent help request can be found in file",
                  file, "\n")
            }
        }
        else cat("The unsent help request can be found in file",
            file, "\n")
    }
    else if (method == "ess") {
        body <- gsub("\\\\n", "\n", body)
        cat(body)
    }
}

-----------------------------------------------------------------------

Gabor Grothendieck wrote:
Here is another update.  I have added the following:

- info about using a fresh R session.  (In that case ls() output is less
  essential; however, the developers of sessionInfo() might consider
  adding that as a default or as an option.)

- questioner should consider use of functions.

- for data use dump(x, file = "") to reproducibly display data or use
  builtin datasets listed by data()

- minimal versions of slow code should be presented in cases where
  questioner is looking for faster code.

- we still need to add links to illustrative sample questions in r-help

The following were not added for the reason cited:

- guide is not just for questioners.  Important to distinguish roles
  of questioner, responder and reader.

- what is to be provided ought to be given a name to make it easier
  to refer to.  An unlabelled set of points is too vague.  Test
  framework seems appropriately descriptive.  By giving it a name
  one can request that a questioner "provide a test framework as
  defined in the posting guide summary".

- self contained is not implied by reproducible.  Reproducible
  only means that info is available somewhere -- not that its all
  available right in the questioner's post and all in a manner that
  is readily accessible.

- focus should be on making data minimal.  Don't like attachments
  since responder must save them and read them in.  It encourages
  use of large rather than minimal data sets.

Summary

Surprisingly, the main problem for responders is not to answer the
question but to quickly figure out what the question is, reproduce it
in their own R session and test their answer.

Test Framework.  To faciliate this provide a test framework of:

  (1) minimal reproducible self-contained commented code and data
      that has been run in a fresh R session.  That means code and
      data have been cut down as far as possible to the essentials
      needed to illustrate the problem and were run are just after
          starting up R.  Also it means that its possible for responders
      to just copy the code and data section from the questioner's
      post to the clipboard and paste it into their session to see
      the same output without having to enter even one R command.
      In some cases there may be an advantage to present the code as
      a function and in the case of needing a speedup be sure to post
      a minimal version of the slow code.  Use builtin data sets such
      as those listed by data() to illustrate problem or reduce your
      data to a minimum and present it reproducibly by using:
         dump("mydata", file = "")

  (2) comments/explanation of what the code is intended to produce
          -- Don't assume its obvious!

  (3) versions of all software used, e.g. sessionInfo(),
          or R.version.string; packageDescription("zoo")$Version

Without self-contained reproducible code the responder must not only
understand the question but must also create a test framework and that
typically takes more time than answering the question!  Its not fair
to ask the responder to provide all that on top of answering the
question.  Do NOT assume the problem is so simple that it is not
necessary.

Effort. The effort taken to reduce the problem to its essentials and
produce a test framework often solves the problem avoiding the need
for a post in the first place.  It at the least shows that the
questioner tried to solve it themself.

Subscribers.  The questioner should ensure that the thread is complete
and that it has an appropriate Subject.  The purpose of the post is
not only to help the questioner but also the other list subscribers
and those later searching the archives.





On Sat, Jun 7, 2008 at 9:38 AM, Gabor Grothendieck
<[EMAIL PROTECTED]> wrote:
Here is a second version of the summary.  Its been rearranged to
place most important info at top.  Also shortened it a bit.

It still needs links to example posts, as suggested.  Anyone?

Summary

Surprisingly, the main problem for responders is not to answer the
posted questions but to quickly figure out what the question is, reproduce
it in their own R session and test their answer.

Test Framework.  To faciliate that provide a test framework of:

 (1) reproducible self-contained minimal code and data.  That means
     responders can copy it from the questioner's post and paste it
     into their session to see the same output without having to
     enter even one R command.
     NB. dput(mydata) produces mydata in reproducible form.
 (2) comments/explanations of what the code is intended to produce and
 (3) versions of all software used, e.g. sessionInfo().

Without self-contained reproducible code the responder must not only
understand the question but must also create a test framework and that
typically takes more time than answering the question!  Its not fair
to ask the responder to provide all that on top of answering the
question.  Do NOT assume the problem is so simple that it is not
necessary.

Effort. The effort taken to reduce the problem to its essentials and
produce a test framework often solves the problem avoiding the need
for a post in the first place.  It at the least shows that the
questioner tried to solve it themself.

Subscribers.  The questioner should ensure that the thread is complete
and that it has an appropriate Subject.  The purpose of the post is
not only to help the questioner but also the other list subscribers
and those later searching the archives.



On Fri, Jun 6, 2008 at 1:30 PM, Gabor Grothendieck
<[EMAIL PROTECTED]> wrote:
People read the posting guide yet they are still unable to create an acceptable
post. e.g.
https://stat.ethz.ch/pipermail/r-help/2008-June/164092.html

I think the problem is that the guide is not clear or concise enough.
I suggest we add a summary at the beginning which gets to the heart
of what a poster is expected to provide:

Summary

To maximize your change of getting a response when posting provide (1)
commented,
(2) minimal, (3) self-contained and (4) reproducible code.  (This one
line summary
also appears at the end of each message to r-help.)

"Self-contained" and "reproducible" mean that a responder can copy the
questioner's code to
the clipboard, paste it into their R session and see the same problem
you as the questioner
see.  Note that dput(mydata) will display mydata in a reproducible way.
Self-contained and reproducible are needed because:
(1) Self-Effort. It shows that the questioner tried to solve the
problem by themself first.
(2) Test framework. Often the responder needs to play with the code a
bit in order to respond
or at least to give the best answer.  They can't do that without a
test framework that includes
the data and the code to run it and its not fair to ask them to not
only answer the question but
also to come up with test data and to complete incomplete code.
(3) Archives. Questions and answers go into the archives so they are
not only for the benefit of
of the questioner but also for the benefit of all future searchers of
the archive.  That means
that its not finished if you have solved the problem for yourself.
You still need to ensure that
the thread has a complete solution. (For that reason its also
important to give a meaningful
subject to each post.)

"Commented" and "minimal" also reduce the time it takes to understand
the problem.
Don't just dump your code as is into the message since you are just
wasting your own
time. Its not likely anyone will answer a message if the questioner
has not taken the
time to reduce it to its essential elements.  Surprisingly, quite
often understanding what
the problem is takes the responder most of the time -- not solving the
problem. Once the
question is actually understood its often quite fast to answer.  Thus
in addition to posting
it in a minimal form, comment on it sufficiently so that the responder
knows what the code
does and is intended to produce.  It may be obvious to the questioner
who is embroiled in
the problem but that does not mean its obvious to others.

Introduction

.... rest of posting guide ...


______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

--
Dr H Turner
Research Fellow
Dept. of Statistics
The University of Warwick
Coventry
CV4 7AL

Tel: 024 76575870
Fax: 024 76524532
Url: www.warwick.ac.uk/go/heatherturner

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to