How can I view the definition of a S4 function? For instance, I would like to see the definition of TSconnect in package TSdbi. The command
showMethods("TSconnect")
reveals that there is, among others, a function for drv="histQuoteDriver", dbname="character".
How can I see the definition of this function? If it were a S3 function, there would be only the first argument definable (drv), which could be inspected with print(TSconnect.histQuoteDriver).
Edit: From r-forge I found out the desired output:
setMethod("TSconnect", signature(drv="histQuoteDriver", dbname="character"),
definition= function(drv, dbname, user="", password="", host="", ...){
# user / password / host for future consideration
if (is.null(dbname)) stop("dbname must be specified")
if (dbname == "yahoo") {
con <- try(url("http://quote.yahoo.com"), silent = TRUE)
if(inherits(con, "try-error"))
stop("Could not establish TShistQuoteConnection to ", dbname)
close(con)
}
else if (dbname == "oanda") {
con <- try(url("http://www.oanda.com"), silent = TRUE)
if(inherits(con, "try-error"))
stop("Could not establish TShistQuoteConnection to ", dbname)
close(con)
}
else
warning(dbname, "not recognized. Connection assumed working, but not tested.")
new("TShistQuoteConnection", drv="histQuote", dbname=dbname, hasVintages=FALSE, hasPanels=FALSE,
user = user, password = password, host = host )
} )
Is there a way to get this definition from within an R session?
S4 classes are relatively complicated, so I would suggest reading this introduction.
In this case, TSdbi is an example of a generic S4 class that gets extended by all the specific databases packages (e.g. TSMySQL, TSPostgreSQL, etc.). There is nothing more to the TSconnect() method in TSdbi than what you're seeing: drv="character", dbname="character" are parameters to the function, not functions in and of themselves. If you install some of the specific database packages and use showMethods("TSconnect") you will see all the specific instances of that function. If you then call TSconnect() with a specific database driver it will go and use the appropriate function.
This is how functions such as summary work too. For instance, try calling showMethods(summary). Depending upon which packages are loaded, you should see multiple methods returned
You can easily see the source code for it on R-Forge: http://r-forge.r-project.org/plugins/scmsvn/viewcvs.php/pkg/TSdbi/R/TSdbi.R?rev=70&root=tsdbi&view=markup. This is the extent of that function:
setGeneric("TSconnect", def= function(drv, dbname, ...) standardGeneric("TSconnect"))
setMethod("TSconnect", signature(drv="character", dbname="character"),
definition=function(drv, dbname, ...)
TSconnect(dbDriver(drv), dbname=dbname, ...))
Related
Below is a snippet of my code that I use in R to extract IDs from a PostgreSQL database. When I run the function I get the following warning message from R:
In result_create(conn#ptr, statement) :
Closing open result set, cancelling previous query
How do I avoid this warning message from happening without making use of options(warn=-1) at the beginning of my code, suppressing the warning instead of
con <- dbConnect(RPostgres::Postgres(),
user = "postgres",
dbname = "DataBaseName",
password = "123456",
port = 5431)
get_id <- function(connection, table){
query <- toString(paste("SELECT id FROM ", table, sep = ""))
data_extract_query <- dbSendQuery(connection, query)
data_extract <- dbFetch(data_extract_query)
return(data_extract)
}
get_id(con, "users")
I found a method for solving the problem.
I found a thread on GitHub for RSQLite a https://github.com/r-dbi/RSQLite/issues/143. In this thread, they explicitly set n = -1 in the dbFetch() function.
This seemed to solve my problem, and the warning message did not show up again by editing the code like the following:
data_extract <- dbFetch(data_extract_query, n = -1)
The meaning of n is the number of rows that the query should return. By setting this to -1 all rows will be retrieved. By default, it is set to n = -1 but for some reason, in this build of R (3.6.3) the warning will still be shown.
Calling ?dbFetch in R you can see more information on this. I have included a snippet from the R-help page:
Usage
dbFetch(res, n = -1, ...)
fetch(res, n = -1, ...)
Arguments
res An object
inheriting from DBIResult, created by dbSendQuery().
n maximum number of records to retrieve per fetch. Use n = -1 or
n = Inf to retrieve all pending records. Some implementations may
recognize other special values.
... Other arguments passed on to methods.
This issue comes up with other database implementations if the results are not cleared before submitting a new one. From the docs of DBI::dbSendQuery
Usage
dbSendQuery(conn, statement, ...)
...
Value
dbSendQuery() returns an S4 object that inherits from DBIResult. The result set can be used with dbFetch() to extract records. Once you have finished using a result, make sure to clear it with dbClearResult(). An error is raised when issuing a query over a closed or invalid connection, or if the query is not a non-NA string. An error is also raised if the syntax of the query is invalid and all query parameters are given (by passing the params argument) or the immediate argument is set to TRUE.
To get rid of the warning the get_id() function must be modified as follows:
get_id <- function(connection, table){
query <- toString(paste("SELECT id FROM ", table, sep = ""))
data_extract_query <- dbSendQuery(connection, query)
data_extract <- dbFetch(data_extract_query)
# Here we clear whatever remains on the server
dbClearResult(data_extract_query)
return(data_extract)
}
See Examples section in help for more.
I've set up a connection between R and SQL using the package RODBC and managed to connect and query the database from R.
I've created a small R function which objective is to delete some lines (as parameter) in a specific table.
Here it is (nameDB is the name of my database, and values_conversion another function I did to convert some data from R format to SQL format) :
delete_SQL = function(data, table){
ch = odbcConnect(nameDB,"postgres")
names = sqlColumns(channel=ch,table,schema="public",catalog = nameDB)$COLUMN_NAME
for(i in 1:nrow(data)){
sqlQuery(channel=ch,query=paste0("DELETE FROM public.\"",table,"\" WHERE ",
paste0(names," = ",values_conversion(data[i,]),collapse = " and "),";"),errors = TRUE)
}
odbcCloseAll()
}
Query exemple : "DELETE FROM public.\"lieu_protection\" WHERE lieu_id = 3 and protection_id = 1430;"
The code inside this function works fine when I execute everything directly, but when I call the function it throws an
Error in sqlQuery(channel = ch, query = paste0("DELETE FROM public.\"", :
first argument is not an open RODBC channel
I have a similar function that's getting and returning data from SQL and which is working fine, so I guess it has something to do with the delete, but the error is about the channel, so I'm quite confused.
Thanks to anyone that can help !
When I start up and R script and I like to check their package versions. I tend to run something like
library(dplyr); packageVersion("dplyr")
This works fine, but I'd like to shorten this to a single function that would load a library and then return its version.
I want the libary function to accept either a string of the library name, or just the library name typed in by itself.
I tried this function:
libver <- function(pac){
if(!is.character(pac)){
pac <- deparse(substitute(pac))
}
library(pac, character.only=TRUE)
packageVersion(pac)
}
But this works for string inputs but not non string inputs
libver(MASS)
Error in libver(MASS): object 'MASS' not found
I can hard code it to take objects rather than strings as follows,
libver <- function(pac){
library( deparse(substitute(pac), character.only=TRUE)
packageVersion(deparse(substitute(pac))
}
but I'd like to keep the flexability to do either one if I can.
!is.character(pac) returns an error when pac is the bare package name, without quotation marks. Instead, you can do pac = as.character(substitute(pac)) which will return a character string, regardless of whether the argument was originally a character string.
libver <- function(pac) {
pac = as.character(substitute(pac))
library(pac, character.only=TRUE)
packageVersion(pac)
}
libver <- function(pac){
pac <- gsub("\"","",deparse(substitute(pac)))
library(pac,character.only = T)
packageVersion(pac)
}
libver(dplyr)
[1] ‘0.7.2’
libver("dplyr")
[1] ‘0.7.2’
I am completely new to R.
I am trying to use the dist object with a custom function based on the specification here, but I was unable to pass the custom function directly by name, so I tried to add it using the registry described here, but it appears that I am missing a library.
However, I'm not sure which library I need and cannot find a reference to find the name of the library.
Here's a code sample that I'm trying to run:
library(cluster)
myfun <- function(x,y) {
numDiffs <- 0;
for (i in x) {
if (x[i] != y[i])
numDiffs <- numDiffs + 1;
}
return(numDiffs);
}
summary(pr_DB)
pr_DB$set_entry(FUN = myfun, names = c("myfun", "vectorham"))
pr_DB$get_entry("MYFUN")
Here's the error:
Error in summary(pr_DB) : object 'pr_DB' not found
Execution halted
You need to learn the conventions used by R help pages. That "{proxy}" at the top of the page you linked to is really the answer to your question. The convention for the help page construction is "topic {package_name}".
I am presently using the streamR package in R to stream tweets from the filter stream in twitter. I have a handshaken ROAuth object that I use for this. My piece of code looks like:
# load the Twitter auth object
load("twitter_oAuth3.RData")
load("keywords3.RData")
streamTweet = function(){
require(streamR)
require(ROAuth)
stack = filterStream(file.name="",track=keywords,timeout=500,oauth=twitter_oAuth)
return(stack)
}
I wanted to create a real time application, which involves dumping these tweets into an activeMQ topic. My code for that is:
require(Rjms)
# Set logger properties
url = "tcp://localhost:61616"
type = "T"
name = "TwitterStream"
# initialize logger
topicWriter = initialize.logger(url,type,name)
topicWrite = function(input){
# print("writing to topic")
to.logger(topicWriter,input,asString=TRUE,propertyName='StreamerID',propertyValue='1')
return()
}
logToTopic = function(streamedStack){
# print("inside stack-writer")
stacklength = length(streamedStack)
print(c("Length: ",stacklength))
for(i in 1:stacklength){
print(c("calling for: ",i))
topicWrite(streamedStack[i])
}
return()
}
Now my problem is that of the timeout that filterStream() needs. I looked under the hood, and found this call that the function makes:
url <- "https://stream.twitter.com/1.1/statuses/filter.json"
output <- tryCatch(oauth$OAuthRequest(URL = url, params = params,
method = "POST", customHeader = NULL,
writefunction = topicWrite, cainfo = system.file("CurlSSL",
"cacert.pem", package = "RCurl")), error = function(e) e)
I tried removing the timeout component but it doesn't seem to work. Is there a way I can maintain a stream forever (until I kill it) which dumps each tweet as it comes into a topic?
P.S. I know of a java implementation that makes a call to the twitter4j API. I, however, have no idea how to do it in R.
The documentation for streamR package mentions that the default option for timeout option in filterStream() is 0 which will keep the connection open permanently.
I quote:
"numeric, maximum length of time (in seconds) of connection to stream. The
connection will be automatically closed after this period. For example, setting
timeout to 10800 will keep the connection open for 3 hours. The default is 0,
which will keep the connection open permanently."
Hope this helps.