Is it possible to #inheritParams from a function within another package? - r

I wrote an importer for an obscure TSV format, which I want to package and document: https://github.com/katrinleinweber/MWX-import/commits/package
The importer function passes a renamed skip_lines parameter to utils::read.table so I would like to "pass" the latter's documentation of skip into my .Rd. However, trying a few notations like #inheritParams utils::read.table skip always results in Warning: Failed to find topic […].
Whether it's actually possible to inherit a single, specific parameter from another package's function is not clear to me after reading http://r-pkgs.had.co.nz/man.html and https://blog.rstudio.org/2017/02/01/roxygen2-6-0-0/.
Is it possible? If yes, thanks for any hint!

If you use #inheritParams utils::read.table, then any parameters in your function which match those in utils::read.table will be inherited (provided they aren't already explicitly documented). So this would cover your use case if you used skip instead of skip_lines.
I don't think it's possible to inherit documentation for a parameter when your parameter name doesn't match though.

Related

DelimitedFiles.readdlm(source, ....) modifies source, is that really intended and where in the documentation/definition is this explained?

surprised to find that DelimitedFiles.readdlm(source, ...) changes the source input parameter. surprised because Ι could find no indication hereof in the official documentation https://docs.julialang.org/en/v1/stdlib/DelimitedFiles/index.html. is this just a standard assumption about mutability in julia? i thought that somefunction that might change an input parameter would indicate this with somefunction! (adding ! to the function name)?
Ι used the function as follows:
out = DelimitedFiles.readdlm(source,',',header=true)
before the call, source has type Array{UInt8,1} and has several elements. after the call, out has type Tuple{Array{Any,2},Array{AbstractString,2}}, source has type Array{UInt8,1} (unchanged) and source is empty (changed).
The reason is that String(vec::Vector{UInt8}) does not perform a copy but takes ownership of vec (and mutates it).
For now you should write:
out = DelimitedFiles.readdlm(copy(source),',',header=true)
I have asked a question here to clarify what is the intended target behavior (copying or non-copying).

What is the difference between ?matrix and ?matrix()

I was going through swirl() again as a refresher, and I've noticed that the author of swirl says the command ?matrix is the correct form to calling for a help screen. But, when I run ?matrix(), it still works? Is there a difference between having and not having a pair of parenthesis?
It's not specific to the swirl environment (about which I was entirely unaware until 5 minutes ago) That is standard for R. The help page for the ? shortcut says:
Arguments
topic
Usually, a name or character string specifying the topic for which help is sought.
Alternatively, a function call to ask for documentation on a corresponding S4 method: see the section on S4 method documentation. The calls pkg::topic and pkg:::topic are treated specially, and look for help on topic in package pkg.
It something like the second option that is being invoked with the command:
?matrix()
Since ?? is actually a different shortcut one needs to use this code to bring up that page, just as one needs to use quoted strings for help with for, if, next or any of the other reserved words in R:
?'?' # See ?Reserved
This is not based on a "fuzzy logic" search in hte help system. Using help instead of ? gets a different response:
> help("str()")
No documentation for ‘str()’ in specified packages and libraries:
you could try ‘??str()’
You can see the full code for the ? function by typing ? at the command line, but I am just showing how it starts the language level processing of the expressions given to it:
`?`
function (e1, e2)
{
if (missing(e2)) {
type <- NULL
topicExpr <- substitute(e1)
}
#further output omitted
By running matrix and in general any_function you get the source code of it.

i don't think i understand function enclosures

I'm trying to package some code I use for data analysis so that other workers can use it. Currently, I'm stuck trying to write a simple function that imports data from a specific file type generated by a datalogger and trims it for use by other functions. Here's the code:
import<-function(filename,type="campbell",nprobes){
if (filename==TRUE){
if (type=="campbell"){
message("File import type is from Campbell CR1000")
flux.data<<-read.table(filename,sep=",",header=T,skip=1)
flux.data<<-flux.data[,-c(1,2)];flux.data<<-flux.data[-c(1,2),]
if (nprobes=="missing"){
nprobes<-32
}
flux.data<<-flux.data[,c(1:nprobes)]
flux.data.names<<-colnames(flux.data) #Saves column names
}
}
}
Ideally, the result would be a dataframe/matrix flux.data and a concomittant vector/list of the preserved column headers flux.data.names. The code runs and the function executes without errors, but the outputs aren't preserved. I usually use <<- to get around the function enclosure but its not working in this case - any suggestions?
I think the real problem is that I don't quite understand how enclosures work, despite a lot of reading... should I be using environment to assign environments within the function?
User joran answered my question in the comments above:
The critical issue was just in how the function was written: the conditional at the start (if filename==TRUE) was intended to see if filename was specified, and instead was checking to see if it literally equaled TRUE. The result was the conditional never being met, and no function output. Here's what fixed it:
import<-function(filename,type="campbell",nprobes){
if (exists(filename){
if (type=="campbell"){
#etc....
Another cool thing he pointed out was that I didn't need the <<- operator to utilize the function output and instead could write return(flux.data). This is a much more flexible approach, and helped me understand function enclosures a lot better.

How to make REST POST calls in R

I have been using jsonlite to make REST GET calls. The number of parameters have increased and I am wondering how to make a REST POST call using R.
Per your request ...
library(jsonlite)
BLUF
Instead of
fromJSON(myurl, ...)
you need to call httr::POST directly:
txt <- httr::POST(myurl, ...)
fromJSON(txt)
Explanation
The basic mechanism for using jsonlite::fromJSON is to pass it a string. In the special case that you pass an URL (regexpr: ^https?://), it does you a courtesy by calling httr::GET and taking its output as your intended input. You can see this intent by looking at its source by typing in jsonlite::fromJSON and finding the line with if(grepl("^https?://" ...; if you try to find the function download_raw, you'll not find immediately since it is an un-exported function. You can find it as jsonlite:::download_raw (notice the third colon).
Looking at that function's source, you'll see that it makes direct calls to httr::GET. You can mimic how download_raw is calling httr::GET, modifying the arguments as needed. (It might be informative to look at both help(httr::GET) and help(httr::POST) and look for the differences between them. Spoiler: look at the body argument, potentially a list for keys/values. The examples are helpful.)

Function signature not found despite showing with methods(...)

I am new to Julia, so this might be trivial.
I have a function definition within a module that looks like (using URIParser):
function add!(graph::Graph,
subject::URI,
predicate::URI,
object::URI)
...
end
Outside of the module, I call:
add!(g, URIParser.URI("http://test.org/1"), URIParser.URI("http://test.org/2"), URIParser.URI("http://test.org/1"))
Which gives me this error:
ERROR: no method add!(Graph,URI,URI,URI)
in include at boot.jl:238
in include_from_node1 at loading.jl:114
at /Users/jbaran/src/RDF/src/RDF.jl:79
Weird. Because when I can see a matching signature:
julia> methods(RDF.add!)
# 4 methods for generic function "add!":
add!(graph::Graph,subject::URI,predicate::URI,object::Number) at /Users/jbaran/src/RDF/src/RDF.jl:29
add!(graph::Graph,subject::URI,predicate::URI,object::String) at /Users/jbaran/src/RDF/src/RDF.jl:36
add!(graph::Graph,subject::URI,predicate::URI,object::URI) at /Users/jbaran/src/RDF/src/RDF.jl:43
add!(graph::Graph,statement::Statement) at /Users/jbaran/src/RDF/src/RDF.jl:68
At first I thought it was my use of object::Union(...), but even when I define three functions with Number, String, and URI, I get this error.
Is there something obvious that I am missing? I am using Julia 0.2.1 x86_64-apple-darwin12.5.0, by the way.
Thanks,
Kim
This looks like you may be getting bit by the very slight difference between method extension and function shadowing.
Here's the short of it. When you write function add!(::Graph, ...); …; end;, Julia looks at just your local scope and sees if add! is defined. If it is, then it will extend that function with this new method signature. But if it's not already defined locally, then Julia creates a new local variable add! for that function.
As JMW's comment suggests, I bet that you have two independent add! functions. Base.add! and RDF.add!. In your RDF module, you're shadowing the definition of Base.add!. This is similar to how you can name a local variable pi = 3 without affecting the real Base.pi in other scopes. But in this case, you want to merge your methods with the Base.add! function and let multiple dispatch take care of the resolution.
There are two ways to get the method extension behavior:
Within your module RDF scope, say import Base: add!. This explicitly brings Base.add! into your local scope as add!, allowing method extension.
Explicitly define your methods as function Base.add!(graph::Graph, …). I like this form as it more explicitly documents your intentions to extend the Base function at the definition site.
This could definitely be better documented. There's a short reference to this in the Modules section, and there's currently a pull request that should be merged soon that will help.

Resources