I am writing a package with a suite of functions that take objects fit to a model (e.g., output from from "lmt", "lavaan", or "mirt" packages) and computes relevant indices based on those models.
The first thing EVERY function in this suite does is convert the input into a standardized form, so all of my functions look like this:
fooIndex <- function(x) {
x <- standardizerFunction(x)
# Now, compute the fooIndex
}
Here, standardizerFunction is an S3 generic function that has methods for all the supported input classes.
Is there a better way to accomplish this functionality than calling standardizerFunction inside of each of the functions computing indices?
EDIT: I just wanted to specify that my "problem" is that copying and pasting the same line of code into ~20 different functions seems like a poor programming style, and I am hoping for a better solution.
Based on what iod and Gregor wrote, the two ways to handle this are:
(1) Require the user to apply the standardizerFunction before running any of the main functions. The functions will the throw an error if the input is of the wrong class.
(2) Since our functions will be checking the input to make sure it is of the right class anyway, just fold standardizerFunction into the input checking part using something like:
if(!inherits(x, what="YourClass")) standardizerFunction(x)
In my particular setting, since most of my users are uncomfortable with R, asking them to pre-apply the standardizerFunction is not the best choice, so I am going with option 2.
Related
I'm working in R, and I'd like to define some variables that I (or one of my collaborators) cannot change. In C++ I'd do this:
const std::string path( "/projects/current" );
How do I do this in the R programming language?
Edit for clarity: I know that I can define strings like this in R:
path = "/projects/current"
What I really want is a language construct that guarantees that nobody can ever change the value associated with the variable named "path."
Edit to respond to comments:
It's technically true that const is a compile-time guarantee, but it would be valid in my mind that the R interpreter would throw stop execution with an error message. For example, look what happens when you try to assign values to a numeric constant:
> 7 = 3
Error in 7 = 3 : invalid (do_set) left-hand side to assignment
So what I really want is a language feature that allows you to assign values once and only once, and there should be some kind of error when you try to assign a new value to a variabled declared as const. I don't care if the error occurs at run-time, especially if there's no compilation phase. This might not technically be const by the Wikipedia definition, but it's very close. It also looks like this is not possible in the R programming language.
See lockBinding:
a <- 1
lockBinding("a", globalenv())
a <- 2
Error: cannot change value of locked binding for 'a'
Since you are planning to distribute your code to others, you could (should?) consider to create a package. Create within that package a NAMESPACE. There you can define variables that will have a constant value. At least to the functions that your package uses. Have a look at Tierney (2003) Name Space Management for R
I'm pretty sure that this isn't possible in R. If you're worried about accidentally re-writing the value then the easiest thing to do would be to put all of your constants into a list structure then you know when you're using those values. Something like:
my.consts<-list(pi=3.14159,e=2.718,c=3e8)
Then when you need to access them you have an aide memoir to know what not to do and also it pushes them out of your normal namespace.
Another place to ask would be R development mailing list. Hope this helps.
(Edited for new idea:) The bindenv functions provide an
experimental interface for adjustments to environments and bindings within environments. They allow for locking environments as well as individual bindings, and for linking a variable to a function.
This seems like the sort of thing that could give a false sense of security (like a const pointer to a non-const variable) but it might help.
(Edited for focus:) const is a compile-time guarantee, not a lock-down on bits in memory. Since R doesn't have a compile phase where it looks at all the code at once (it is built for interactive use), there's no way to check that future instructions won't violate any guarantee. If there's a right way to do this, the folks at the R-help list will know. My suggested workaround: fake your own compilation. Write a script to preprocess your R code that will manually substitute the corresponding literal for each appearance of your "constant" variables.
(Original:) What benefit are you hoping to get from having a variable that acts like a C "const"?
Since R has exclusively call-by-value semantics (unless you do some munging with environments), there isn't any reason to worry about clobbering your variables by calling functions on them. Adopting some sort of naming conventions or using some OOP structure is probably the right solution if you're worried about you and your collaborators accidentally using variables with the same names.
The feature you're looking for may exist, but I doubt it given the origin of R as a interactive environment where you'd want to be able to undo your actions.
R doesn't have a language constant feature. The list idea above is good; I personally use a naming convention like ALL_CAPS.
I took the answer below from this website
The simplest sort of R expression is just a constant value, typically a numeric value (a number) or a character value (a piece of text). For example, if we need to specify a number of seconds corresponding to 10 minutes, we specify a number.
> 600
[1] 600
If we need to specify the name of a file that we want to read data from, we specify the name as a character value. Character values must be surrounded by either double-quotes or single-quotes.
> "http://www.census.gov/ipc/www/popclockworld.html"
[1] "http://www.census.gov/ipc/www/popclockworld.html"
Help files call attributes() a function. Its syntax looks like a function call. Even class(attributes) calls it a function.
But I see I can assign something to attributes(myobject), which seems unusual. For example, I cannot assign anything to log(myobject).
So what is the proper name for "functions" like attributes()? Are there any other examples of it? How do you tell them apart from regular functions? (Other than trying supposedfunction(x)<-0, that is.)
Finally, I guess attributes() implementation overrides the assignment operator, in order to become a destination for assignments. Am I right? Is there any usable guide on how to do it?
Very good observation Indeed. It's an example of replacement function, if you see closely and type apropos('attributes') in your R console, It will return
"attributes"
"attributes<-"
along with other outputs.
So, basically the place where you are able to assign on the left sign of assignment operator, you are not calling attributes, you are actually calling attributes<- , There are many functions in R like that for example: names(), colnames(), length() etc. In your example log doesn't have any replacement counterpart hence it doesn't work the way you anticipated.
Definiton(from advanced R book link given below):
Replacement functions act like they modify their arguments in place,
and have the special name xxx<-. They typically have two arguments (x
and value), although they can have more, and they must return the
modified object
If you want to see the list of these functions you can do :
apropos('<-$') and you can check out similar functions, which has similar kind of properties.
You can read about it here and here
I am hopeful that this solves your problem.
I know that while and if functions in R are not vectorised. while and if functions help us selectively work on some rows based on some condition. I also know that the apply function in R is used to apply over the columns and hence it operates on all rows of columns that we wish to put apply on. Can I use apply() along with user defined functions and/or with while/if loop to conditionally use it over some rows rather than all rows as apply function usually does.
Note :- This core issue here is to bypass the drawback on non-vectorization of while/if loops in R.
You can supply user defined functions to apply using an argument FUN = function(x) user_defined_function(x) {}. And apply is "vectorized" in sense that as argument it accept vectors, not scalars (but its implementation is heavily using for and if loops, type apply without arguments in your console). So for and apply are of the same perfomance.
However you can break the execution of user defined function throwing exception with stop and wrapping in tryCatch it is a non-recommended technique (it influences environements, call stacks, scopes etc., make debugging difficult and lead to errors which are difficult to identify).
Better to use for and if and very often it is the most easiest and effective way (to write a recursive function, taking in consideration that (tail) recursion is not really optimized for R, or fully refactor your algorithm quite difficult and time consuming).
I have two containers, conty and contx. The values of both are tied to each other. conty[1] relates to contx[1] etc. while using apply on contx I want to access the index inside an apply structure so I can put values from corresponding element in conty into contz depending upon the index of x.
lapply(contx, function(x) {
if (x==1) append(contz,conty[xindex])
})
I could easily do this in a for loop but everybody insists that using the apply is better. And I tried to look for examples but the only thing I could find was mostly stuff for generating maps where it wasn't entirely clear how I could adapt to my problem.
There are a few issues here.
"everybody insists that using the apply is better". Sorry, but they're wrong; it's not necessarily better. See the old-school Burns Inferno ("If you are using R and you think you’re in hell, this is a map for you"), chapter 4 ("Overvectorization"):
A common reflex is to use a function in the apply family. This is not vectorization, it is loop-hiding. The apply function has a for loop in its definition. The lapply function buries the loop, but execution times tend to be roughly equal to an explicit for loop ... Base your decision of using an apply function on Uwe’s Maxim (page 20). The issue is of human time rather than silicon chip time. Human time can be wasted by taking longer to write the code, and (often much more importantly) by taking more time to understand subsequently what it does.
However, what you are doing that's bad is growing an object (also covered in the Inferno). Assuming that in your example contz started as an empty list, this should work (is my example reflective of your use case?)
x <- c(1,2,3,1)
conty <- list("a","b","c","d")
contz <- conty[which(x==1)]
Alternatively, if you want to use both the value and the index in your function, you can write a two-variable function f(val,index) and then use Map(f,my_list,seq_along(my_list))
This is more of a general code structuring question.
At the moment I try to write my code into "namespaces". So for example, I would have:
Mine.FancyPlot.Plot(...)
Mine.FancyPlot.Impl.PlotCanvas(...)
Mine.FancyPlot.Impl.PlotLegend(...)
Mine.BasicPlot.Plot(...)
Mine.BasicPlot.Impl.PlotCanvas(...)
Mine.BasicPlot.Impl.PlotLegend(...)
Mine.BasicPlot.Impl.PlotLines(...)
The idea is that I am trying to hide away "private" functions in a "Impl" for implementation namespace. So outside of Mine_FancyPlot.R I wouldn't call Mine.FancyPlot.Impl functions.
This approach works reasonably well, except code completion isn't as nice as it could be.
To begin with, when I type Mine.BasicPlot. and hit TAB, I get all functions, including the Impl functions, and because I is before P, they even hide the "public" user functions.
So I started changing the structure to
MyPub.FancyPlot.Plot(...)
MyPriv.FancyPlot.PlotCanvas(...)
MyPriv.FancyPlot.PlotLegend(...)
MyPub.BasicPlot.Plot(...)
MyPriv.Mine.BasicPlot.PlotCanvas(...)
MyPriv.Mine.BasicPlot.PlotLegend(...)
MyPriv.Mine.BasicPlot.PlotLines(...)
This works better in that "private" functions are no longer predicted. However, I still have the issue that if I type MyPub. and hit TAB, I can't actually see all different "namespaces" (such as I would in Java, C++, ...), but rather a long list of functions starting all in the first "namespace".
Ideally, I'd like code completion in R to cut off all predictions at the next dot, and unique them, so Ideally when I type MyPub. and hit TAB, I would only get a list of "sub-namespaces" and functions in MyPub.
Is this possible? Can the code prediction be altered to reflect this behaviour? Or is there a better way to achieve what I am aiming for?
You should consider putting your functions in a package to organise them. Functions that are not exported will only be accessible by doing 'package:::functionNotExported' and will not be listed when just doing 'functionNotExpo[tab]'
See for instance debugging a function in R that was not exported by a package