Creating private values from other private values in R6 - r

Is there any way to use a private value in order to create another private value inside R6Class()? I am getting errors.
obj <- R6Class(
"abc",
private = list(
a = 2,
b = 2*private$a
)
)
Error in all_named(private) : object 'private' not found
I have also tried to create b with b = 2 * a, but it is still impossible. How should I go about it?
Thank you

obj <- R6Class(
"abc",
private = list(
a = 2,
b = function() 2*self$a
)
)

Related

How to get/build a JavaRDD[DataSet]?

When I use deeplearning4j and try to train a model in Spark
public MultiLayerNetwork fit(JavaRDD<DataSet> trainingData)
fit() need a JavaRDD parameter,
I try to build like this
val totalDaset = csv.map(row => {
val features = Array(
row.getAs[String](0).toDouble, row.getAs[String](1).toDouble
)
val labels = Array(row.getAs[String](21).toDouble)
val featuresINDA = Nd4j.create(features)
val labelsINDA = Nd4j.create(labels)
new DataSet(featuresINDA, labelsINDA)
})
but the tip of IDEA is No implicit arguments of type:Encode[DataSet]
it's a error and I dont know how to solve this problem,
I know SparkRDD can transform to JavaRDD, but I dont know how to build a Spark RDD[DataSet]
DataSet is in import org.nd4j.linalg.dataset.DataSet
Its construction method is
public DataSet(INDArray first, INDArray second) {
this(first, second, (INDArray)null, (INDArray)null);
}
this is my code
val spark:SparkSession = {SparkSession
.builder()
.master("local")
.appName("Spark LSTM Emotion Analysis")
.getOrCreate()
}
import spark.implicits._
val JavaSC = JavaSparkContext.fromSparkContext(spark.sparkContext)
val csv=spark.read.format("csv")
.option("header","true")
.option("sep",",")
.load("/home/hadoop/sparkjobs/LReg/data.csv")
val totalDataset = csv.map(row => {
val features = Array(
row.getAs[String](0).toDouble, row.getAs[String](1).toDouble
)
val labels = Array(row.getAs[String](21).toDouble)
val featuresINDA = Nd4j.create(features)
val labelsINDA = Nd4j.create(labels)
new DataSet(featuresINDA, labelsINDA)
})
val data = totalDataset.toJavaRDD
create JavaRDD[DataSet] by Java in deeplearning4j official guide:
String filePath = "hdfs:///your/path/some_csv_file.csv";
JavaSparkContext sc = new JavaSparkContext();
JavaRDD<String> rddString = sc.textFile(filePath);
RecordReader recordReader = new CSVRecordReader(',');
JavaRDD<List<Writable>> rddWritables = rddString.map(new StringToWritablesFunction(recordReader));
int labelIndex = 5; //Labels: a single integer representing the class index in column number 5
int numLabelClasses = 10; //10 classes for the label
JavaRDD<DataSet> rddDataSetClassification = rddWritables.map(new DataVecDataSetFunction(labelIndex, numLabelClasses, false));
I try to create by scala:
val JavaSC: JavaSparkContext = new JavaSparkContext()
val rddString: JavaRDD[String] = JavaSC.textFile("/home/hadoop/sparkjobs/LReg/hf-data.csv")
val recordReader: CSVRecordReader = new CSVRecordReader(',')
val rddWritables: JavaRDD[List[Writable]] = rddString.map(new StringToWritablesFunction(recordReader))
val featureColnum = 3
val labelColnum = 1
val d = new DataVecDataSetFunction(featureColnum,labelColnum,true,null,null)
// val rddDataSet: JavaRDD[DataSet] = rddWritables.map(new DataVecDataSetFunction(featureColnum,labelColnum, true,null,null))
// can not reslove overloaded method 'map'
debug error infomations:
A DataSet is just a pair of INDArrays. (inputs and labels)
Our docs cover this in depth:
https://deeplearning4j.konduit.ai/distributed-deep-learning/data-howto
For stack overflow sake, I'll summarize what's here since there's no "1" way to create a data pipeline. It's relative to your problem. It's very similar to how you you would create a dataset locally, generally you want to take whatever you do locally and put that in to spark in a function.
CSVs and images for example are going to be very different. But generally you use the datavec library to do that. The docs summarize the approach for each kind.

Update a dependent field in R6 object when a parent field is updated

I'm new to R6 and object oriented programming, so i'm not sure the right way to even talk about dependencies between fields inside an object.
My objects have fields that are dependent on other fields inside the object. I would like those dependent fields to automatically update when one of the inputs is updated.
I have figured out a manual way of doing this, but thought that there may be a better way. I played around with active fields but i could not get them to work.
This example should make it clear. I have an object quad that takes width and height and calculates area. I would like area to be automatically updated when width or height are updated.
This seems to be one of the things that active fields are intended to achieve, but i couldn't make them work.
For the purpose of exposition i hacked to my goal by including a re-calculation line for self$area in the set method for each field.
How is this supposed to be done?
library(R6)
quad <- R6Class("quad", public =
list(width = NULL,
height = NULL,
area = NULL,
initialize = function(width, height) {
self$width <- width
self$height <- height
self$area = self$width * self$height
self$greet()
},
set_width = function(W) {
self$width <- W
self$area = self$width * self$height #hack
},
set_height = function(H) {
self$height <- H
self$area = self$width * self$height #hack
},
greet = function() {
cat(paste0("your quad has area: ", self$area, ".\n"))
})
)
#
> quad1 <- quad$new(5, 5)
your quad has area: 25.
> quad1$set_height(10)
> quad1$area
[1] 50
An active binding is essentially a function that is invoked without needing to use (), so it looks like a regular field.
In the example below, area is an active binding and is computed each time you access it.
library(R6)
Quad <- R6Class(
"Quad",
public = list(
initialize = function(width, height) {
self$width <- width
self$height <- height
},
width = NULL,
height = NULL
),
active = list(
area = function() {
self$width * self$height
}
)
)
q <- Quad$new(8, 3)
q$area
#> [1] 24
q$height <- 5
q$area
#> [1] 40

R, R6, Formals for Public Method

How can I get the formals for a method definition in an R6 class definition?
A = R6Class("MyClass",inherit=NULL,
public = list(
fun = function(a,b,c){
# Do Something
}
)
)
So for example, in the above, I would like to get the formals for the fun definition, in the same way one can execute, for example, formals(lm)
You can do this by creating an instance of the class:
A = R6Class("MyClass",
inherit=NULL,
public = list(
a = NA,
initialize = function(a){
self$a <- a
},
fun = function(a,b,c){
# Do Something
}
)
)
B <- A$new(5)
formals(B$fun)
or by accessing the public methods of the class
formals(A$public_methods$fun)

Testing private methods in R6 classes in R

I am currently using R6 classes in a project.
I would like to write unit tests that also test the functionality of private methods that I am using (preferably by not going through the more complicated public methods that are using these private methods).
However, I can't access seem to access the private methods.
How do I best do that?
Thanks!
Here is a solution that does not require environment hacking or altering the class you want to test, but instead creating a new class that does the testing for you.
In R6, derived classes have access to private Methods of their base classes (unlike in C++ or Java where you need the protected keyword to archieve the same result). Therefore, you can write a TesterClass that derives from the class you want to test. For example:
ClassToTest <- R6::R6Class(
private = list(
privateMember = 7,
privateFunction = function(x) {
return(x * private$privateMember)
}
)
)
TesterClass <- R6::R6Class(
inherit = ClassToTest,
public = list(
runTest = function(x = 5) {
if (x * private$privateMember != private$privateFunction(x))
cat("Oops. Somethig is wrong\n")
else
cat("Everything is fine\n")
}
)
)
t <- TesterClass$new()
t$runTest()
#> Everything is fine
One advantage of this approach is that you can save detailed test results in the TesterClass.
There is currently a way to access the private environment of an R6 object. However, since this is reaching into an object in an undocumented way, it may break in the future... I don't think that will happen any time soon though.
# Gets private environment from an R6 object
get_private <- function(x) {
x[['.__enclos_env__']]$private
}
A <- R6::R6Class("A",
private = list(x = 1)
)
a <- A$new()
get_private(a)$x
# [1] 1
you can add a helper method get to your class:
...
A <- R6::R6Class(
"A",
private = list(
private_print = function(){print("Ola")}
),
public = list(
get = function(name=NULL){
# recursion
if( length(name)>1 ){
tmp <- lapply(name, self$get)
names(tmp) <- name
return(tmp)
}
if(is.null(name)){
self$message("no input, returning NULL")
return(NULL)
}
# self
if(name=="self"){
return(self)
}
# in self
if( name %in% names(self) ){
return(base::get(name, envir=self))
}
# private or in private
if( exists("private") ){
if(name=="private"){
return(private)
}else if(name %in% names(private) ){
return(base::get(name, envir=private))
}
}
# else
self$message("name not found")
return(NULL)
}
)
)
...
Than use it like this:
a <- A$new()
a$get("private_print")()
## [1] "Ola"

Instantiation of reference classes within reference classes - problems with lock() and immutability

I have come across some behaviour from R reference classes I would like to work around. In the following code, reference class B has two fields of reference class A in it.
These fields in B appear to be instantiated (possibly twice) with a zero-argument (default) versions of reference class A before B's initialize() method is called. These instances are then replaced with the correct versions of instance A during B's initialization process. The problem is that if I use lock() from B's instance generator, the initial empty instantiation's of A cannot be replaced in B. Another problem is that reference class A needs a default value in initialize [or a missing(c) test].
Help - suggestions - etc. appreciated.
A <- setRefClass('A',
fields = list(
count = 'numeric'
),
methods = list(
initialize = function (c=0) {
cat('DEBUG: A$initialize(c); where c='); cat(c); cat('\n')
count <<- c
}
)
)
instance.of.A <- A$new(10)
str(instance.of.A)
B <- setRefClass('B',
field = list(
a = 'A',
b = 'A'
),
methods = list(
initialize = function(c) {
a <<- instance.of.A
b <<- getRefClass('A')$new(c)
}
)
)
instance.of.b <- B$new(100)
str(instance.of.b)
Here are two possible solutions:
Don't set fields attribute:
B <- setRefClass('B',
methods = list(
initialize = function(c) {
.self$a = instance.of.A
.self$b =getRefClass('A')$new(c)
}
)
)
Set fields, but use the ANY class:
B <- setRefClass('B',
field = (a="ANY", b="ANY"),
methods = list(
initialize = function(c) {
a <<- instance.of.A
b <<- getRefClass('A')$new(c)
}
)
)
The downside of both these solutions is the type isn't enforced in a and b, i.e.
B$a = "Fred"
is now possible.
Drawing on the above, the solution I am using is (a little long because of the type checking):
A <- setRefClass('A',
fields = list(
count = function(x) {
if (!missing(x)) {
if(class(x) != 'numeric')
stop('Class A: count set by non-number')
.self$count.private <- x
}
.self$count.private
}
),
methods = list(
initialize = function (c=0) {
cat('DEBUG: A$initialize(c); where c='); cat(c); cat('\n')
count <<- c
}
)
)
instance.of.A <- A$new(10)
str(instance.of.A)
B <- setRefClass('B',
field = list(
a = function(x) {
if (!missing(x)) {
if(!inherits(x, 'envRefClass') || class(x)[1] != 'A')
stop('Class B: expecting instance of class A')
.self$a.private <- x
}
.self$a.private
},
b = function(x) {
if (!missing(x)) {
if(!inherits(x, 'envRefClass') || class(x)[1] != 'A')
stop('Class B: expecting instance of class A')
.self$b.private <- x
}
.self$b.private
}
),
methods = list(
initialize = function(c) {
a <<- instance.of.A
b <<- getRefClass('A')$new(c)
}
)
)
instance.of.b <- B$new(100)
str(instance.of.b)

Resources