Change initialize method in subclass of an R6 class - r

Let's say I have a R6 class Person:
library(R6)
Person <- R6Class("Person",
public = list(name = NA, hair = NA,
initialize = function(name, hair) {
self$name <- name
self$hair <- hair
self$greet()
},
greet = function() {
cat("Hello, my name is ", self$name, ".\n", sep = "")
})
)
If I want to create a subclass whose initialize method should be the same except for adding one more variable to self how would I do this?
I tried the following:
PersonWithSurname <- R6Class("PersonWithSurname",
inherit = Person,
public = list(surname = NA,
initialize = function(name, surname, hair) {
Person$new(name, hair)
self$surname <- surname
})
)
However when I create a new instance of class PersonWithSurname the fields name and hair are NA, i.e. the default value of class Person.
PersonWithSurname$new("John", "Doe", "brown")
Hello, my name is John.
<PersonWithSurname>
Inherits from: <Person>
Public:
clone: function (deep = FALSE)
greet: function ()
hair: NA
initialize: function (name, surname, hair)
name: NA
surname: Doe
In Python I would do the following:
class Person(object):
def __init__(self, name, hair):
self.name = name
self.hair = hair
self.greet()
def greet(self):
print "Hello, my name is " + self.name
class PersonWithSurname(Person):
def __init__(self, name, surname, hair):
Person.__init__(self, name, hair)
self.surname = surname

R6 works very much like Python in this regard; that is, you just call initialize on the super object:
PersonWithSurname <- R6Class("PersonWithSurname",
inherit = Person,
public = list(surname = NA,
initialize = function(name, surname, hair) {
super$initialize(name, hair)
self$surname <- surname
})
)

Related

How to show all Elements in a Textview

data class Fruit(val name: String, val price: Int)
val fruits = arrayOf(Fruit(name = "Apple", price = 2), Fruit(name = "Grape", price = 3), Fruit(name = "Bananna", price = 4))
for (index in fruits.indices)
textView.text = fruits[index].name
Output = Bananna
I cant seem to get all elements of "Name" to reflect in the Textview
Eg.
Apple, Grape, Pear
I manage to figure it out !
val fruitNamesonly: MutableList<String> = ArrayList()
for (item in fruits) {
val token = item.name
FruitNamesonly.add(token)
}
val fruitNamesonly will be the vaulable you use for what ever

How to integrate database connection to R6 class in R

Hello I would like to assign a dbConnection to a R6 class but it fails.
LastProfilZdb <- R6Class(
classname = "LastProfilZdb",
public = list(
name = NULL,
zp = NULL,
data = NULL ,
zp_id = function() {
pool::poolWithTransaction(self$db_server, function(conn){
DBI::dbGetQuery(conn, paste0("SELECT ZP_ID FROM
ZP_ID WHERE LP_ZP = '", self$zaehlpunkt,
"' OR ZP_NAME_SAP = '", self$zaehlpunkt, "'"))
})
},
#....
#....
initialize = function(){
message("Init Data Base Connection")
#
self$db_server <- pool::dbPool(drv = odbc::odbc(),
dsn = "Oracle",
schema = "schema" )
},
finalize = function() {
message("Closing Data Base Connection")
pool::poolClose(self$db_server)
}
),
private = list(
# db Connection is stored in the calss so we don't need to care any more
# This way, input data can be collected in a neat way,
# and stored inside our object.
db_server = NULL
)
)
This fails with error:
Error in self$db_server <- pool::dbPool(drv = odbc::odbc(), dsn = "Oracle", :
cannot add bindings to a locked environment
What can I do?

R: Assign vector element as list variable name

Here is the end result that I would like to achieve:
json_creative_pause = list("47770124" =
list(patch = list(
`$set` = list (
status = "PAUSED"
))))
The issue is that I would like to create this same structure dynamically for multiple ids. I have this variable:
creative_ids_to_pause = c("75196186", "78369656", "80050466")
And I would like to recreate the same structure for each creative id. But running such code doesn't really work:
json_creative_pause = list(get(creative_ids_to_pause[1]) =
list(patch = list(
`$set` = list (
status = "PAUSED"
))))
Does anyone know how to assign a vector element as a variable name inside of a list?
Thank you for your help!
Arben
We can use setNames
setNames(list(patch = list(
`$set` = list (
status = "PAUSED"
))), creative_ids_to_pause[1])
#$`75196186`
#$`75196186`$`$set`
#$`75196186`$`$set`$status
#[1] "PAUSED"
Or another option is dplyr::lst
dplyr::lst(!! creative_ids_to_pause[1] :=
list(patch = list(
`$set` = list (
status = "PAUSED"
))))
#$`75196186`
#$`75196186`$patch
#$`75196186`$patch$`$set`
#$`75196186`$patch$`$set`$status
#[1] "PAUSED"
I also found this solution:
creative_ids_to_pause = c("75196186", "78369656", "80050466")
unnamed_json_structure = list(
patch = list(
`$set` = list(
status = "PAUSED"
)))
list_all_creative_ids = list()
for(i in 1:length(creative_ids_to_pause)){
list_all_creative_ids[[creative_ids_to_pause[i]]] = unnamed_json_structure
}
list_all_creative_ids %>%
toJSON(pretty = TRUE, auto_unbox = TRUE)
Result
"75196186": {
"patch": {
"$set": {
"status": "PAUSED"
}
}
},
"78369656": {
"patch": {
"$set": {
"status": "PAUSED"
}
}
},
"80050466": {
"patch": {
"$set": {
"status": "PAUSED"
}
}
}
}

Access elements of an R6 class that instantiates another R6 class

Say I have a class SimpleClass and one of the methods of that class can return an object of another class, e.g.
SimpleClass <- R6::R6Class(
"SimpleClass",
public = list(
initialize = function() {
private$a <- 1
},
cls_two = function() SimpleClass2$new()
),
private = list(
a = numeric()
)
)
Where SimpleClass2 is
SimpleClass2 <- R6::R6Class(
"SimpleClass2",
public = list(
initialize = function() {
private$b <- 2
},
get_a = function() private$a
),
private = list(
b = numeric()
)
)
Here, if I were instantiate SimpleClass and call the method cls_two(), the resulting object will not have access to the elements of the first object unless I pass them on. Is there a way for the secondary class to access elements of the first class?
first <- SimpleClass$new()
second <- first$cls_two()
second$get_a()
# NULL
Note that I do not want to use inheritance in the traditional sense because I do not want to reinstantiate the first class. I would also prefer not to have to pass on all of the objects to SimpleClass2$new().
Extend SimpleClass2’s constructor to take an object of type SimpleClass, and pass self when calling the constructor in SimpleClass::cls_two:
SimpleClass2 <- R6::R6Class(
"SimpleClass2",
public = list(
initialize = function(obj) {
private$b <- 2
private$obj <- obj
},
get_a = function() private$obj
),
private = list(
b = numeric(),
obj = NULL
)
)
You can make SimpleClass2 have a member that is a Simpleclass and have an option to pass a simpleclass in its constructor:
SimpleClass <- R6::R6Class(
"SimpleClass",
public = list(
initialize = function() {
private$a <- 1
},
cls_two = function() SimpleClass2$new(self)
),
private = list(
a = numeric()
)
)
SimpleClass2 <- R6::R6Class(
"SimpleClass2",
public = list(
initialize = function(Simp1 = SimpleClass$new()) {
private$a <- Simp1
private$b <- 2
},
get_a = function() private$a
),
private = list(
a = SimpleClass$new(),
b = numeric()
)
)
Which works like this:
first <- SimpleClass$new()
second <- first$cls_two()
second$get_a()
#> <SimpleClass>
#> Public:
#> clone: function (deep = FALSE)
#> cls_two: function ()
#> initialize: function ()
#> Private:
#> a: 1

How to have observable treeview

I am working on an app which requires TreeView.
I'm able to generate the Treeview but facing issue with dynamically updating the treeview based on underlying dataset change.
Classes:
data class Channels(
val channel: Channel? = null
)
data class Channel(
val id: String? = null,
val name: String? = null,
val parentChannelId: String? = null
)
Data List :
var channels = observableListOf(
Channels(channel = Channel(id = "pc1", name = "P Channel 1")),
Channels(channel = Channel(id = "c11", name = "Child 1-1", parentChannelId = "pc1")),
Channels(channel = Channel(id = "c12", name = "Child 1-2", parentChannelId = "pc1")),
Channels(channel = Channel(id = "c121", name = "Child 1-2-1", parentChannelId = "c12")),
Channels(channel = Channel(id = "c111", name = "Child 1-1-1", parentChannelId = "c11")),
Channels(
channel = Channel(
id = "c1111",
name = "Child 1-1-1-1",
parentChannelId = "c111"
)
),
Channels(channel = Channel(id = "pc2", name = "P Channel 2")),
Channels(channel = Channel(id = "pc3", name = "P Channel 3")),
Channels(channel = Channel(id = "c31", name = "Child 3-1", parentChannelId = "pc3"))
)
Treeview :
treeview<Channels> {
isShowRoot = false
root = TreeItem()
cellFormat { text = it.channel?.name }
populate { parent ->
if (parent == root) channels.filter {
it.channel?.parentChannelId == null
} else channels.filter {
it.channel?.parentChannelId == parent.value?.channel?.id
}
}
}
Now when I modify the channels list, treeview doesn't gets updated.
I've been stuck on this since 3-4 days.
Please help.

Resources