At the moment, I am switching from Python to R and I am trying to write some simple code to price a portfolio, using Jeff Ryan's Ibrokers package. I would like to have a field of class twsconn in one of my objects
setClass( "MktAsset",
representation( IB.id = "character",
asset.type = "factor",
ccy = "factor",
IB.conn = "twsconn") )
but the system does not seem happy about it
Msg is
In .completeClassSlots(ClassDef, where) :
undefined slot classes in definition of "MktAsset": IB.connection(class "twsconn")
but when I ask the class of tws (initialized with tws <- twsConnect(), it returns
[1] "twsconn" "environment"
I tried to go through the code to check for the existence of a class twsconn but, I found nothing.
Can someone help?
Thanks a lot
The issue is S3 in S4. This should work:
setOldClass("twsconn") # this is what you are missing
setClass( "MktAsset",
representation( IB.id = "character",
asset.type = "factor",
ccy = "factor",
IB.conn = "twsconn") )
# [1] "MktAsset"
a <- new("MktAsset")
ibg <- ibgConnect() # connect to IB Gateway
a#IB.conn <- ibg
a
An object of class "MktAsset"
Slot "IB.id":
character(0)
Slot "asset.type":
factor(0)
Levels:
Slot "ccy":
factor(0)
Levels:
Slot "IB.conn":
<twsConnection,1 # 20110325 13:15:22 CST, nextId=1>
If you're able to come to R/Finance in Chicago in April www.RinFinance.com, I'll be doing a two-hour workshop on Friday
morning (April 29th) regarding IBrokers (and algorithmic trading in general with R)
that would be of interest I suspect.
Related
Trying to build a new class on the base of an 'ordered' class, using R.version 3.3.1 tried also on new R-devel
R Under development (unstable) (2016-10-26 r71594) -- "Unsuffered Consequences"
I get an error:
> setClass('newFactor', representation = c(tempValue = 'character'), contains = c('ordered'))
Error in validObject(.Object) :
invalid class “classRepresentation” object: invalid object for slot "slots" in class "classRepresentation": got class "character", should be or extend class "list"
>
The same thing works on the stable Version 3.2.5
EDIT
OK thanks #hrbrmstr I understood that R 3.3 does not support using S3 objects inside S4 objects but I am still puzzled. This:
numWithId <- setClass("numWithId", slots = c(id = "character"),contains = "numeric")
should work but this :
numWithId <- setClass("numWithId", slots = c(id = "character"),contains = "factor")
should not, except it does!
> numWithId <- setClass("numWithId", slots = c(id = "character"),contains = 'factor')
> new('numWithId')
An object of class "numWithId"
integer(0)
Slot "id":
character(0)
Slot "levels":
character(0)
Slot ".S3Class":
[1] "factor"
On the other hand this does not work:
numWithId <- setClass("numWithId", slots = c(id = "character"),contains = 'ordered')
Error in makePrototypeFromClassDef(properties, ClassDef, immediate, where) :
in constructing the prototype for class “numWithId”: prototype has class “S4”, but the data part specifies class “integer”
When I add list to the contains = it works {I have a feeling that this is not the right way of doing this}
> setClass("numWithId", slots = c(id = "character"),contains = c('list', 'ordered'))
> new("numWithId")
An object of class "numWithId"
list()
Slot "id":
character(0)
Slot ".S3Class":
[1] "ordered" "factor"
Slot "levels":
character(0)
>
What is the right way of inheriting an S3 object in to an S4 object?
As part of an assignment in college I am trying to make a small r package that provides some basic statistics and graphics on GTFS feeds.
I am using the files from https://github.com/ondrejivanic/131500/blob/master/gtfs.r.
I have to create a number of S4 classes to as part of the assignment. I have created a separate classes for each GTFS feed file. I am trying to make a list of service id's to produce a graphic for the number of trips on a given day.
Here I define and create and object of the class.
# Create the S4 Class for calendar_dates.txt
# calendar_dates.txt - service_id, date, exception_type
setClass("CalendarDates", representation(service_id = "factor", date = "POSIXct", exception_type = "numeric"))
# create new object of SHAPES from files
calendar_dates <- transform(
read.gtfs.file("calendar_dates.txt", "data"),
date = ymd(date)
)
# create S4 object of routes
calendar_datesS4 <- new("CalendarDates", service_id = calendar_dates$service_id, date = calendar_dates$date, exception_type = calendar_dates$exception_type)
The part I cannot understand is how to perform this subset on an S4 object. The piece below works with a dataframe object:
calendar.dates <- calendar_datesS4
calendar.dates[calendar.dates$date == d & calendar.dates$exception_type == 1, c("service_id")]
[1] "daily_1" "daily_2" "daily_3" "daily_4"
Doing the following results in an error:
calendar.dates[calendar.dates#date == d & calendar.dates#exception_type == 1, c("service_id")]
Error in calendar.dates[dates == d & exceptions == 2, c("service_id")] :
object of type 'S4' is not subsettable
I have not found any questions elsewhere, where a condition must be met for the subset.
I really appreciate any help with this!
My aim is to define one of the slots of class Security as another class Quote.
First I define class Quote:
Quote <- setClass("Quote", slots = c(Last = "numeric", Settle = "numeric"))
Then I am trying to define class Security as following:
Security <- setClass("Security", slots = c(Name = "character", Price = "Quote"))
Finally I am trying to create constructor for class Security:
Security <- function(Name = character(), Last = numeric(), Settle = numeric())
new("Security", Name = Name, Price#Last = Last, Price#Settle = Settle)
Unfortunately, this code doesn't work...
Thanks in advance.
If offering the user a constructor named Security, make sure the default constructor is named differently
.Security <- setClass("Security", slots = c(Name = "character", Price = "Quote"))
In your own constructor, create the slot instance as an argument to default constructor; use ... to allow for class inheritance
Security <-
function(Name = character(), Last = numeric(), Settle = numeric(), ...)
{
.Security(Name=Name, Price=Quote(Last=Last, Settle=Settle), ...)
}
I'm still trying to learn S4, and I see that a recognized expert has already given an answer, so I'm mostly posting this as an example for critique:
.Quote <- setClass("Quote", slots = c(Last = "numeric", Settle = "numeric"))
.Security <- setClass("Security", slots = c(Name = "character", Price = "Quote"))
aNewSecurity <- .Security(Name = "newSec",
Price = .Quote(Last =20, Settle = 40) )
aNewSecurity
An object of class "Security"
Slot "Name":
[1] "newSec"
Slot "Price":
An object of class "Quote"
Slot "Last":
[1] 20
Slot "Settle":
[1] 40
I'm not sufficiently knowledgeable to know if separating Quote items from Security items is needed in this domain.
I am getting the message
Error in parent.frame() : node stack overflow
Error during wrapup: node stack overflow
when I try to construct an object using the S4 command "as", but only when a superclass is declared "VIRTUAL".
The class hierarchy is as follows:
PivotBasic contains Pivot contains Model
The setClass commands for Pivot and Pivot Basic and the constructor for PivotBasic are below. Class Pivot does not have a constructor. The Model constructor is too big to insert here.
This is really not a big deal (I think) because everything works fine if the "VIRTUAL" keyword is removed from the representation argument of setClass. But I am curious about the reason for the problem. Would anyone have insights on it?
Thanks,
Fernando Saldanha
setClass(Class = "Pivot",
representation = representation(
pivotName = "character",
pivotNames = "character",
pivotData = "data.frame",
"VIRTUAL"
),
contains = "Model"
)
setClass(Class = "PivotBasic",
representation = representation(),
contains = "Pivot"
)
pivotBasic <- function(
portfolio,
assets,
controlVariableList,
pivotData = NULL, # pivotName is ignored if pivotData is not null
pivotName = "N_WEEKDAY_3_6",
firstPredictionDate = as.Date(integer(), origin = "1970-01-01"),
name = NULL,
tags = "Event"
) {
if (missing(portfolio)) stop("[PivotBasic: pivotBasic] - Missing portfolio argument")
if (missing(assets)) stop("[PivotBasic: pivotBasic] - Missing assets argument")
if (missing(controlVariableList)) stop("[PivotBasic: pivotBasic] - Missing controlVariableList argument")
object <- model(
portfolio,
assets,
controlVariableList,
firstPredictionDate,
name,
tags)
# The error message happens when this command is executed
mdl <- as(object, "PivotBasic")
# Other code
mdl
} # end pivotBasic
Is this a minimal example that illustrates your problem
.Model <- setClass(Class = "Model",
representation=representation(x="integer")
)
setClass(Class = "Pivot",
representation = representation("VIRTUAL"),
contains = "Model"
)
.PivotBasic <- setClass(Class = "PivotBasic",
contains = "Pivot"
)
This generates an error
> as(.Model(), "PivotBasic")
Error: evaluation nested too deeply: infinite recursion / options(expressions=)?
> R.version.string
[1] "R version 3.0.0 Patched (2013-04-15 r62590)"
but might generate an error like you see under an earlier version of R. This thread on the R-devel mailing list is relevant, where a solution is to define a setIs method such as
setIs("PivotBasic", "Model",
coerce = function(from) .PivotBasic(x = from#x),
replace = function(from, value) {
from#x = value#x
from
}
)
I think of setIs as part of the class definition. If there are many slots needing copying, then a further work-around might be, in the replace function,
nms <- intersect(slotNames(value), slotNames(from))
for (nm in nms)
slot(from, nm) <- slot(value, nm)
from
but the underlying issue is really in S4's implementation. A cost to removing the "VIRTUAL" specification is that it compromises your class design, and presumably the formalism of the S4 system is what motivated your choice in the first place; maybe that's not such a bad cost when faced with the alternatives.
I am trying to use the structure() function to create a data frame in R.
I saw something like this
structure(mydataframe, class="data.frame")
Where did class come from? I saw someone using it, but it is not listed in the R document.
Is this something programmers learned in another language and carries it over? And it works. I am very confused.
Edit: I realized dput(), is what actually created a data frame looking like this. I got it figured out, cheers!
You probably saw someone using dput. dput is used to post (usually short) data. But normally you would not create a data frame like that. You would normally create it with the data.frame function. See below
> example_df <- data.frame(x=rnorm(3),y=rnorm(3))
> example_df
x y
1 0.2411880 0.6660809
2 -0.5222567 -0.2512656
3 0.3824853 -1.8420050
> dput(example_df)
structure(list(x = c(0.241188014013708, -0.522256746461544, 0.382485333260912
), y = c(0.666080872170054, -0.251265630627216, -1.84200501106852
)), .Names = c("x", "y"), row.names = c(NA, -3L), class = "data.frame")
Then, if someone wants to "copy" your data.frame, he just has to run the following:
> copied_df <- structure(list(x = c(0.241188014013708, -0.522256746461544, 0.382485333260912
+ ), y = c(0.666080872170054, -0.251265630627216, -1.84200501106852
+ )), .Names = c("x", "y"), row.names = c(NA, -3L), class = "data.frame")
I put "copy" in quotes because note the following:
> identical(example_df,copied_df)
[1] FALSE
> all.equal(example_df,copied_df)
[1] TRUE
identical yields false because when you post your dput output, often the numbers get rounded to a certain decimal point.
'class' is not a specific argument to the structure function - that's why you didn't find it in the help file.
structure takes an object and then any number of name/value pairs and sets them as attributes on the object. In this case, class was such an attribute. You can try this to add fictional 'foo' and 'bar' attributes to a vector:
x <- structure(1:3, foo=42, bar='hello')
attributes(x)
#$foo
#[1] 42
#
#$bar
#[1] "hello"
And as Joshua Ulrich and Xu Wang mentioned, you should not create a data.frame like that.
I'm scratching my head, wondering what "R Document" would not have said something about "class". It's a very basic component of the the language and how functions get applied. You should type this and read:
?class
?methods