I am learning R6 and plan to use it in the Shiny app I am developing. My goal is to separate business logic from the app interface and reuse it across different modules and sub-modules, as suggested in the book Engineering Production-Grade Shiny Apps.
My current approach is as follows:
library(R6)
library(tibble)
Stack_Overflow <- R6Class(
classname = "Stack_Overflow_example",
public = list(
vec1 = c(1, 2, 3),
vec2 = c(4, 5, 6),
vec3 = c(7, 8, 9),
form_tibble = \() {
tibble(
vec_1 = self$vec1,
vec_2 = self$vec2,
vec_3 = self$vec3
)
}
)
)
When I call form_tibble()
, I get the expected tibble:
example <- Stack_Overflow$new()
example$form_tibble()
> example$form_tibble()
# A tibble: 3 × 3
vec_1 vec_2 vec_3
<dbl> <dbl> <dbl>
1 1 4 7
2 2 5 8
3 3 6 9
However, I'd like to apply this technique to my real project, in which an R6 class object may contain more than 30 variables, assuming they have the same length. While I could copy and paste to form the tibble structure like the example above, my understanding of R suggests that this should be possible to generate dynamically—I’m just not sure how to implement it in R6.
Given this context, I have two questions:
Convert to a list using as.list.R6()
, remove elements that are environments or functions, then coerce to a tibble:
library(R6)
library(tibble)
Stack_Overflow <- R6Class(
classname = "Stack_Overflow_example",
public = list(
vec1 = c(1, 2, 3),
vec2 = c(4, 5, 6),
vec3 = c(7, 8, 9),
form_tibble = \() {
self_l <- as.list(self)
self_l <- self_l[!(sapply(self_l, typeof) %in% c("environment", "closure"))]
# for some reason the list elements are in reverse order - so use `rev()`
as_tibble(rev(self_l))
}
)
)
example <- Stack_Overflow$new()
example$form_tibble()
# # A tibble: 3 × 3
# vec1 vec2 vec3
# <dbl> <dbl> <dbl>
# 1 1 4 7
# 2 2 5 8
# 3 3 6 9
Depending on what your actual object looks like, you may have to modify to filter out other object types or based on other conditions.