I am trying to understand how the SVM predict function works when using command ksvm from R package kernlab.
I tried the look into the predict function using the following commands:
methods(class="ksvm")
getAnywhere(ksvm:::predict)
However, I get the following output and not the complete predict function:
A single object matching ‘:::’ ‘ksvm’ ‘predict’ was found
It was found in the following places
package:base
namespace:base
with value
function (pkg, name)
{
pkg <- as.character(substitute(pkg))
name <- as.character(substitute(name))
get(name, envir = asNamespace(pkg), inherits = FALSE)
}
<bytecode: 0x00000000088be4f8>
<environment: namespace:base>
Warning message:
In find(x, numeric = TRUE) :
elements of 'what' after the first will be ignored
Can someone help with how to obtain the complete predict function?
Update 1:
Suggestion from misspelled worked fine on predict function for ksvm in kernlab package but doesn't seem to work on svm in e1071 package.
It throws the following error:
> getMethod("predict", "svm")
Error in getMethod("predict", "svm") :
no generic function found for 'predict'
In general, how to know which get method to use?
You were close. I was able to get the function code with getMethod("predict", "ksvm"). This answer describing S4 method dispatch was helpful. View source code for function
Per your updated question, I can get the source code for predict.svm using the ::: function. Specifically with e1071:::predict.svm. The link above also describes this in the section on S3 method dispatch.
There are at least a couple of things going on here. First is that in the former case you are dealing with S4 objects and S3 objects in the latter. The two systems have different method dispatches and different ways to view the source code. Another wrinkle is that the predict.svm function is an invisible function and can only be viewed either with ::: or getAnywhere().
Related
In source code of R randomForest package, I find the following code in grow.R. What's the purpose for UseMethod? Why does function grow not have function definition and just grow.default and grow.randomForest have definition? Is this something related to calling C function in the R package?
grow <- function(x, ...) UseMethod("grow")
grow.default <- function(x, ...)
stop("grow has not been implemented for this class of object")
grow.randomForest <- function(x, how.many, ...) {
y <- update(x, ntree=how.many)
combine(x, y)
}
Also, in the randomForest.R file, I only find the following code. There is randomForest.default.R file too. Why is there no randomForest.randomForest definition like function grow?
"randomForest" <-
function(x, ...)
UseMethod("randomForest")
What's the purpose for UseMethod? Why does function grow not have function definition and just grow.default and grow.randomForest have definition?
I'd suggest reading about S3 dispatch to understand the patterns you see. Advanced R has a chapter on S3. You can also see related questions here on Stack Overflow.
Is this something related to calling C function in the R package?
No.
Why is there no randomForest.randomForest definition like function grow?
This should make sense if you do the recommended reading above. S3 dispatch uses a pattern of function_name.class to call the correct version of the function (method) based on class of the input. You don't give a randomForest object as an input to the randomForest function, so there is no randomForest.randomForest method defined.
grow() does get called on randomForest objects, hence the grow.randomForest() method. Presumably the authors wanted grow() to error early if it gets called on inappropriate input, so the default for other classes is an immediate error, but they still keep dispatch flexible to work with other classes, enabling extensions of the package and nice play with other packages that may have their own grow() implementations.
I am experiencing some confusing behavior from gamlss in R. The documentation lists predict.gamlss and ?predict.gamlss returns the function documentation in RStudio. However, the function does not autocomplete when typing out predict.gamlss, and trying to run it returns Error: 'predict.gamlss' is not an exported object from 'namespace:gamlss'. How does that happen? Is the function deactivated somehow? There is a separate function predictAll that does work.
The documentation does state
This function is under development
I am trying to access the function because I am experiencing some confusing results with predict and predictAll.
R version is 4.0.0. gamlss version is 5.1.6.
As far as I can tell, what you describe is expected and is normal S3 method dispatching. The method predict.gamlss is called when you call predict on a object of class gamlss.
Consider the following (from the documentation of ?predict.gamlss)
data(abdom)
aa <- gamlss(y ~ cs(x^.5), data = abdom)
#[1] 371.3931
predict(aa)[610]
Looking at the class of aa:
class(aa)
#[1] "gamlss" "gam" "glm" "lm"
The function is not exported, but the S3 method is registered.
As to the difference between predictAll and predict.gamlss, you'll have to read the documentation (the two are documented together). My guess is that predictAll predict all listed in the what-argument of predict.gamlss.
I'm trying to call the Error() function but it says could not find function "Error". I checked the docs and Error does not seem to be a part of R base package. This is a very hard function to search for because "Error" is a very overloaded word. What package is Error() in? For context, I'm running an anova. I'm pretty sure that this isn't a user defined since I see multiple tutorials referencing it without defining.
EDIT:
Here are the tutorials:
https://datascienceplus.com/two-way-anova-with-repeated-measures/ , http://personality-project.org/r/r.guide/r.anova.html#withinone (look at usages of Error() in within sujects/repeated measures anova)
EDIT2:
Here is the model answer from the tutorial. There does not seem to be any information about how the 'Error' function is defined or where it comes from:
model <- aov(wm$iq ~ wm$condition + Error(wm$subject / wm$condition))
The Error() in this case is specifying the error term for the aov function. It's a parameter passed to the function aov() and thus is not a function on its own. I've also tried searching for Error using the package sos, which yields 0 results:
# install.packages("sos")
library(sos)
results <- findFn("Error")
filtered_results <- results[results$Function == 'Error']
nrow(filtered_results)
Output:
[1] 0
You might want to read this Cross Validated post on how to set the Error term within the aov() function.
I am trying to view the source code of the function knnreg in caret.
> getAnywhere(knnreg.default)
A single object matching ‘knnreg.default’ was found
It was found in the following places
package:caret
registered S3 method for knnreg from namespace caret
namespace:caret
with value
function (x, ...)
{
if (!any(class(x) %in% "formula"))
stop("knnreg only implemented for formula objects")
}
<environment: namespace:caret>
What's happening? Where is the source code?
I think the error message is pretty obvious:
knnreg only implemented for formula objects
Use getAnywhere(knnreg.formula) to see the source code.
I'm working on an R package where one of the functions contains a match.fun call to a function in a package that's imported to the package namespace. But on loading the package, the match.fun call can't find the function name. From Hadley Wickham's description I think I'm doing everything right, but this is clearly not the case.
Example:
# in the package file header, for creation of the NAMESPACE via roxygen2:
##` #import topicmodels
# The function declaration in the package
ModelTopics <- function(doc.term.mat, num.topics, topic.method="LDA"){
topic.fun <- match.fun(topic.method)
output <- topic.fun(doc.term.mat, k=num.topics)
return(output)
}
And then in R:
> library(mypackage)
> sample.output <- ModelTopics(my.dtm, topic.method="LDA", num.topics=5)
Error in get(as.character(FUN), mode = "function", envir = envir) :
object 'LDA' of mode 'function' was not found
From my understanding of namespaces, the match.fun call should have access to the package namespace, which should include the topicmodels functions. But that doesn't appear to be the case here. If I import topicmodels directly to the global namespace for the R session, then this works.
Any help is much appreciated. This is R64 2.14.1 running on OSX.
UPDATE:
The package is here
Re the DESCRIPTION file, perhaps that's the problem: roxygen2 doesn't update the DESCRIPTION file with Imports: statements. But none of the other packages are listed there, either; only the match.fun calls appear to be affected.
Re the NAMESPACE extract, here's the import section:
import(catspec)
import(foreach)
import(gdata)
import(Hmisc)
import(igraph)
import(lsa)
import(Matrix)
import(plyr)
import(RecordLinkage)
import(reshape)
import(RWeka)
import(stringr)
import(tm)
import(topicmodels)
I believe this an issue of scope. Although you have imported topicmodels and thus LDA, you haven't exported these functions, so they aren't available in the search path.
From ?match.fun:
match.fun is not intended to be used at the top level since it will
perform matching in the parent of the caller.
Thus, since you are using ModelTopics in the global environment, and LDA isn't available in the global environment, the match.fun call fails.
It seems to me you have two options:
Option 1: use get
An alternative would be to use get where you can specify the environment. Consider this: try to use match.fun to find print.ggplot in the package ggplot2:
match.fun("print.ggplot")
Error in get(as.character(FUN), mode = "function", envir = envir) :
object 'print.ggplot' of mode 'function' was not found
Since print.ggplot isn't exported, match.fun can't find it.
However, get does find it:
get("print.ggplot", envir=environment(ggplot))
function (x, newpage = is.null(vp), vp = NULL, ...)
{
set_last_plot(x)
if (newpage)
grid.newpage()
data <- ggplot_build(x)
gtable <- ggplot_gtable(data)
if (is.null(vp)) {
grid.draw(gtable)
}
else {
if (is.character(vp))
seekViewport(vp)
else pushViewport(vp)
grid.draw(gtable)
upViewport()
}
invisible(data)
}
<environment: namespace:ggplot2>
Option 2: Export the functions from topicmodels that you need
If you make the necessary functions from topicmodels available in your NAMESPACE, your code should also work.
Do this by either:
Selective exporting LDA and other functions to the namespace using #export
Declare a dependency, using Depends: topicmodels - this is the same as calling library(topicmodels) in the global environment. This will work, but is possibly a bit of a brute force approach. It also means that any subsequent library call can mask your LDA function, thus leading to unexpected results.
Answering my own question: the DESCRIPTION file wasn't updating the Imports: and Depends: fields after re-roxygenizing the updated code. Hence the match.fun issues. Out of curiousity, why does this affect match.fun but not a range of other function calls made elsewhere to imported package functions?