Problem with using barplot and scatter plot in leaflet - leaflet

I am trying to have both a scatter plot and a barplot in leaflet. The datetable, the leaflet and the scatter plot work fine. The problem is
the barplot does not work when in leaflet we select some points in map as shown in the following figure. Why scatter plot works fine but bar plot does not?
How to solve this problem? Here is the R code:
#R code
library(leaflet)
library(crosstalk)
library(DT)
library(dplyr)
library(htmltools)
library(summarywidget)
library(plotly)
#devtools::install_github("jcheng5/d3scatter")
library(d3scatter)
data_2<-structure(list(ID = 1:8, Name1 = c("A", "A", "A", "C", "B", "B",
"A", "B"), Name2 = c("a", "b", "b", "a", "b", "a", "b", "c"),
Value1 = c(12, 43, 54, 34, 23, 77, 44, 22), Value2 = c(0,
1, 1, 0, 0, 0, 0, 2), Lat = c(51.1, 51.6, 57.3, 52.4, 56.3,
54.3, 60.4, 49.2), Lon = c(5, -3, -2, -1, 4, 3, -5, 0), lab_DB = c("blue",
"blue", "blue", "green", "red", "red", "blue", "red")), class = "data.frame", row.names = c(NA,-8L))
sdf <- SharedData$new(data_2, key=~ID)
lmap <- leaflet(data = sdf) %>% addTiles() %>%
addCircleMarkers(data = sdf,
lng = ~Lon,
lat = ~Lat,
group = ~Name1 ,color = ~lab_DB
,radius =3
)
dtable <- datatable(sdf , width = "100%",editable=TRUE)
ggplt<-ggplot(sdf, aes(x=factor(Value2)))+
geom_bar(stat="count", width=0.7, fill="steelblue")
d3<-d3scatter(sdf , x=~Value1 ,y=~Value2, width="100%", height=300)
bscols( widths=c(6,6,0), list(lmap, d3),list(dtable,ggplotly(ggplt)))
The below code shows the counts of #0, #1 and #2 for "value2" calculated correctly! (showed in the caption of datatable) but something wrongs with barplot!!
#R code
library(leaflet)
library(crosstalk)
library(DT)
library(dplyr)
library(htmltools)
library(summarywidget)
library(plotly)
#devtools::install_github("jcheng5/d3scatter")
library(d3scatter)
data_2<-structure(list(ID = 1:8, Name1 = c("A", "A", "A", "C", "B", "B",
"A", "B"), Name2 = c("a", "b", "b", "a", "b", "a", "b", "c"),
Value1 = c(12, 43, 54, 34, 23, 77, 44, 22), Value2 = c(0,
1, 1, 0, 0, 0, 0, 2), Lat = c(51.1, 51.6, 57.3, 52.4, 56.3,
54.3, 60.4, 49.2), Lon = c(5, -3, -2, -1, 4, 3, -5, 0), lab_DB = c("blue",
"blue", "blue", "green", "red", "red", "blue", "red")), class = "data.frame", row.names = c(NA,-8L))
sdf <- SharedData$new(data_2, key=~ID)
lmap <- leaflet(data = sdf) %>% addTiles() %>%
addCircleMarkers(data = sdf,
lng = ~Lon,
lat = ~Lat,
group = ~Name1 ,color = ~lab_DB
,radius =3
)
ggplt<-ggplotly(sdf %>% ggplot( aes(x=factor(Value2)))+
geom_bar(stat="count", width=0.7, fill="steelblue"))
d3<-d3scatter(sdf , x=~Value1 ,y=~Value2, width="100%", height=300)
dtable <- datatable(sdf , width = "100%",editable=TRUE,
caption=tags$caption("Value2: #0: ",summarywidget(sdf , selection=~Value2==0)
," Value2: #1: ",summarywidget(sdf , selection=~Value2==1)
," Value2: #1: ",summarywidget(sdf , selection=~Value2==2)
))
bscols( list(lmap, dtable),list(d3,ggplt), htmltools::p(summarywidget(sdf , selection=~Value2==0,column="Value2")
,summarywidget(sdf , selection=~Value2==1,column="Value2")
,summarywidget(sdf , selection=~Value2==2,column="Value2")
, style="display:none;"))

Here is a solution with shiny. Again I use a callback function with your datatable to subset the shared data sdf so you can click the column you are interested in and display a bar chart:
library(shiny)
library(leaflet)
library(crosstalk)
library(DT)
library(dplyr)
library(htmltools)
library(summarywidget)
library(plotly)
library(d3scatter)
data_2 <- structure(
list(ID = 1:8,
Name1 = c("A", "A", "A", "C", "B", "B", "A", "B"),
Name2 = c("a", "b", "b", "a", "b", "a", "b", "c"),
Value1 = c(12, 43, 54, 34, 23, 77, 44, 22),
Value2 = c(0, 1, 1, 0, 0, 0, 0, 2),
Lat = c(51.1, 51.6, 57.3, 52.4, 56.3, 54.3, 60.4, 49.2),
Lon = c(5, -3, -2, -1, 4, 3, -5, 0),
lab_DB = c("blue", "blue", "blue", "green", "red", "red", "blue", "red")),
class = "data.frame",
row.names = c(NA,-8L))
ui <- fluidPage(
fluidRow(
column(6, leafletOutput("lmap")),
column(6, d3scatterOutput("scatter"))
),
fluidRow(
column(6, DTOutput("table")),
column(6,
style = "padding-top: 105px;",
plotlyOutput("plot"))
)
)
server <- function(input, output) {
sdf <- SharedData$new(data_2, key=~ID)
output$lmap <- renderLeaflet({
leaflet(data = sdf) %>%
addTiles() %>%
addCircleMarkers(data = sdf,
lng = ~Lon,
lat = ~Lat,
group = ~Name1 ,color = ~lab_DB,
radius =3)
})
output$scatter <- renderD3scatter({
d3scatter(sdf,
x = ~Value1 ,
y = ~Value2,
width = "100%",
height=300)
})
output$table <- renderDT({
datatable(
sdf,
filter = 'top',
editable=TRUE,
extensions = c('Select', 'Buttons'),
selection = 'none',
options = list(select = list(style = 'os',
items = 'row'),
dom = 'Bfrtip',
autoWidth = TRUE,
buttons = list('copy' ,
list(extend = 'collection',
buttons = c('csv', 'excel', 'pdf', 'print'),
text = 'Download'))),
caption = tags$caption("Value2: #0: ",
summarywidget(sdf, selection = ~Value2 == 0),
" Value2: #1: ", summarywidget(sdf, selection = ~Value2 == 1),
" Value2: #2: ", summarywidget(sdf, selection = ~Value2 == 2)),
# This part is new: callback to get col number as `input$col`
callback = JS("table.on('click.dt', 'td', function() {
var col=table.cell(this).index().column;
var data = [col];
Shiny.onInputChange('col',data );
});")
)
},
server = FALSE)
# plotly bar chart
output$plot <- renderPlotly({
req(input$col)
dat <- sdf$data(withSelection = TRUE) %>%
filter(selected_ == TRUE) %>%
pull(input$col) %>%
table()
fig <- plot_ly(
x = names(dat),
y = dat,
name = "Count",
type = "bar"
)
fig
})
}
shinyApp(ui, server)
If you are only interested in column Value2 then the approach below works as well:
library(shiny)
library(leaflet)
library(crosstalk)
library(DT)
library(dplyr)
library(htmltools)
library(summarywidget)
library(plotly)
library(d3scatter)
data_2 <- structure(
list(ID = 1:8,
Name1 = c("A", "A", "A", "C", "B", "B", "A", "B"),
Name2 = c("a", "b", "b", "a", "b", "a", "b", "c"),
Value1 = c(12, 43, 54, 34, 23, 77, 44, 22),
Value2 = c(0, 1, 1, 0, 0, 0, 0, 2),
Lat = c(51.1, 51.6, 57.3, 52.4, 56.3, 54.3, 60.4, 49.2),
Lon = c(5, -3, -2, -1, 4, 3, -5, 0),
lab_DB = c("blue", "blue", "blue", "green", "red", "red", "blue", "red")),
class = "data.frame",
row.names = c(NA,-8L))
ui <- fluidPage(
fluidRow(
column(6, leafletOutput("lmap")),
column(6, d3scatterOutput("scatter"))
),
fluidRow(
column(6, DTOutput("table")),
column(6,
style = "padding-top: 105px;",
plotlyOutput("plot"))
)
)
server <- function(input, output) {
sdf <- SharedData$new(data_2, key=~ID)
output$lmap <- renderLeaflet({
leaflet(data = sdf) %>%
addTiles() %>%
addCircleMarkers(data = sdf,
lng = ~Lon,
lat = ~Lat,
group = ~Name1 ,color = ~lab_DB,
radius =3)
})
output$scatter <- renderD3scatter({
d3scatter(sdf,
x = ~Value1 ,
y = ~Value2,
width = "100%",
height=300)
})
output$table <- renderDT({
datatable(
sdf,
filter = 'top',
editable=TRUE,
extensions = c('Select', 'Buttons'),
selection = 'none',
options = list(select = list(style = 'os',
items = 'row'),
dom = 'Bfrtip',
autoWidth = TRUE,
buttons = list('copy' ,
list(extend = 'collection',
buttons = c('csv', 'excel', 'pdf', 'print'),
text = 'Download'))),
caption = tags$caption("Value2: #0: ",
summarywidget(sdf, selection = ~Value2 == 0),
" Value2: #1: ", summarywidget(sdf, selection = ~Value2 == 1),
" Value2: #2: ", summarywidget(sdf, selection = ~Value2 == 2))
)
},
server = FALSE)
# plotly bar chart
output$plot <- renderPlotly({
dat <- sdf$data(withSelection = TRUE) %>% filter(selected_ == TRUE)
p <- ggplot(data = dat,
aes(x=factor(Value2))) +
geom_bar(stat="count", width=0.7, fill="steelblue")
ggplotly(p)
})
}
shinyApp(ui, server)

Related

Why the content of some cells is modified following knitting of a kable object?

I have started today working with kableExtra to create tables in R markdown.
I am satisfied with the output of the script when run.
However, following knitting the value that are in the (00) format representing percentages are unexpectedly changed to 00. with a change in alignment.
Is there a. way to correct this, please?
library(tidyverse)
library(kableExtra)
df <- data.frame(matrix(nrow = 5, ncol = 0))
df <- df %>%
mutate(X1 = c("a", "b", "c", "d", "e"),
X2 = c("n (%)", "n (%)", "median (IQR)", "median (IQR)", "n (%)"),
X3 = c(5,6,2,4,5),
x4 = c("(15)", "(23)", "(1-3)", "(2-5)", "(15)"))
kable(df, col.names = c("", "", "", ""), align = c("l", "l", "r", "l")) %>%
kable_styling(bootstrap_options = "condensed", full_width = FALSE) %>%
add_header_above(c("Number of cases" = 2, "60" = 2), line = FALSE) %>%
add_header_above(c(" " = 2, "Admission" = 2), line = FALSE) %>%
add_header_above(c("Table 1." = 4), align = "left") %>%
column_spec(c(3:4), width = "3em") %>%
column_spec(c(2), width = "7em") %>%
column_spec(c(1), width = "6em") %>%
footnote(general = "IQR, interquantile range")
It appears to be an issue only when within the brackets there is an integer number. Adding a decimal digit to the percentages solved the problem.
I have used sprintf to force the maintenance of a single digit (even when .0) in my actual code with round_half_up.
Here is the reproducible code instead.
df <- data.frame(matrix(nrow = 5, ncol = 0))
df <- df %>%
mutate(X1 = c("a", "b", "c", "d", "e"),
X2 = c("n (%)", "n (%)", "median (IQR)", "median (IQR)", "n (%)"),
X3 = c(5,6,2,4,5),
x4 = c("(15.8)", "(23)", "(1-3)", "(2-5)", "(15.0)"))
kable(df, col.names = c("", "", "", ""), align = c("l", "l", "r", "l")) %>%
kable_styling(bootstrap_options = "condensed", full_width = FALSE) %>%
add_header_above(c("Number of cases" = 2, "60" = 2), line = FALSE) %>%
add_header_above(c(" " = 2, "Admission" = 2), line = FALSE) %>%
add_header_above(c("Table 1." = 4), align = "left") %>%
column_spec(c(3:4), width = "3em") %>%
column_spec(c(2), width = "7em") %>%
column_spec(c(1), width = "6em") %>%
footnote(general = "IQR, interquantile range")
enter image description here

How do you remove empty rows and add descriptive columns?

A follow-up question to this one
Once I introduce some more complexity in my table, I'm seeing empty rows where no group-subgroup combination exists. Could those be remove?
I'm also wanting to add a "descriptive" column which does not fit into the cell-row-column tabulation, could I do that?
Here's an example:
animals_2 <- data.table(
family = rep(c(1, 1, 1, 1, 1, 1, 2, 2 ,2 ,3 ,3 ,3), 2),
animal = rep(c(1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4), 2),
name = rep(c(rep("fred", 3), rep("tod", 3), rep("timmy", 3), rep("johnno", 3)), 2),
age = rep(c(1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3), 2),
field = c(rep(1, 12), rep(2, 12)),
value = c(c(25, 45, 75, 10, 25, 50, 10, 15, 25, 5, 15, 20), c(5, 15, 30, 3, 9, 13, 2, 5, 9, 1, 2, 3.5))
)
animals_2 <- expss::apply_labels(
animals_2,
family = "|",
family = c("mammal" = 1, "reptilia" = 2, "amphibia" = 3),
animal = "|",
animal = c("dog" = 1, "cat" = 2, "turtle" = 3, "frog" = 4),
name = "|",
age = "age",
age = c("baby" = 1, "young" = 2, "mature" = 3),
field = "|",
field = c("height" = 1, "weight" = 2),
value = "|"
)
expss::expss_output_viewer()
animals_2 %>%
expss::tab_cells(value) %>%
expss::tab_cols(age %nest% field) %>%
expss::tab_rows(family %nest% animal) %>%
expss::tab_stat_sum(label = "") %>%
expss::tab_pivot()
You will see the column "name" doesn't feature in the table currently. I would just like to put it next to each animal and before the Age/Field summaries. Is this possible?
Thanks in advance!
As for empty categories - there is a special function for that - 'drop_empty_rows':
library(expss)
animals_2 <- data.table(
family = rep(c(1, 1, 1, 1, 1, 1, 2, 2 ,2 ,3 ,3 ,3), 2),
animal = rep(c(1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4), 2),
name = rep(c(rep("fred", 3), rep("tod", 3), rep("timmy", 3), rep("johnno", 3)), 2),
age = rep(c(1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3), 2),
field = c(rep(1, 12), rep(2, 12)),
value = c(c(25, 45, 75, 10, 25, 50, 10, 15, 25, 5, 15, 20), c(5, 15, 30, 3, 9, 13, 2, 5, 9, 1, 2, 3.5))
)
animals_2 <- expss::apply_labels(
animals_2,
family = "|",
family = c("mammal" = 1, "reptilia" = 2, "amphibia" = 3),
animal = "|",
animal = c("dog" = 1, "cat" = 2, "turtle" = 3, "frog" = 4),
name = "|",
age = "age",
age = c("baby" = 1, "young" = 2, "mature" = 3),
field = "|",
field = c("height" = 1, "weight" = 2),
value = "|"
)
expss::expss_output_viewer()
animals_2 %>%
expss::tab_cells(value) %>%
expss::tab_cols(age %nest% field) %>%
expss::tab_rows(family %nest% animal %nest% name) %>%
expss::tab_stat_sum(label = "") %>%
expss::tab_pivot() %>%
drop_empty_rows()
As for column "name" - you can add name to value label with pipe separator: dog|fred' or as in the example above, via%nest%`.
UPDATE:
If you need it as column with heading then it is better to place names as statistics:
animals_2 %>%
expss::tab_rows(family %nest% animal) %>%
# here we create separate column for name
expss::tab_cols(total(label = "name")) %>%
expss::tab_cells(name) %>%
expss::tab_stat_fun(unique) %>%
# end of creation
expss::tab_cols(age %nest% field) %>%
expss::tab_cells(value) %>%
expss::tab_stat_sum(label = "") %>%
expss::tab_pivot(stat_position = "outside_columns") %>%
drop_empty_rows()

How do you remove the cell label from your table?

I'm trying to leverage expss to automate some reporting currently done in Excel via R. I'm generally needing to summarise a lot of values across some grouping (rows) relative to some fields (columns). I'm finding it difficult to get rid of the cell description.
Here's an example:
animals <- data.table(
animal = c(1, 1, 2, 2, 3, 3, 4, 4),
standing = c(1, 2, 1, 2, 1, 2, 1 ,2),
height = c(50, 70, 75, 105, 25, 55, 10, 20)
)
animals <- expss::apply_labels(
animals,
animal = "animal",
animal = c("cat" = 1, "dog" = 2, "turtle" = 3, "rat" = 4),
standing = "standing",
standing = c("no" = 1, "yes" = 2),
height = "height"
)
expss::expss_output_viewer()
animals %>%
expss::tab_cells(height) %>%
expss::tab_cols(animal) %>%
expss::tab_rows(standing) %>%
expss::tab_stat_sum(label = "") %>%
expss::tab_pivot()
You will see that "height" is printed as a label, how do I get rid of it please?
Thanks!
"|" assigned as label suppress both label and variable name:
library(expss)
animals <- data.table(
animal = c(1, 1, 2, 2, 3, 3, 4, 4),
standing = c(1, 2, 1, 2, 1, 2, 1 ,2),
height = c(50, 70, 75, 105, 25, 55, 10, 20)
)
animals <- expss::apply_labels(
animals,
animal = "animal",
animal = c("cat" = 1, "dog" = 2, "turtle" = 3, "rat" = 4),
standing = "standing",
standing = c("no" = 1, "yes" = 2),
height = "|" # to suppress label
)
expss::expss_output_viewer()
animals %>%
expss::tab_cells(height) %>%
expss::tab_cols(animal) %>%
expss::tab_rows(standing) %>%
expss::tab_stat_sum(label = "") %>%
expss::tab_pivot()

How do you map over the values of Zip2?

I have two arrays like [1, 2, 3] and ["a", "b", "c"] and I want to map over the zipped values (1, "a"), (2, "b"), and (3, "c") using Zip2.
If I do this:
let foo = map(Zip2([1, 2, 3], ["a", "b", "c"]).generate()) { $0.0 }
foo has the type ZipGenerator2<IndexingGenerator<Array<Int>>, IndexingGenerator<Array<String>>>?.
Is there a way to make that an array?
The following will get you an array from the return value of Zip2:
var myZip = Zip2([1, 2, 3], ["a", "b", "c"]).generate()
var myZipArray: Array<(Int, String)> = []
while let elem = myZip.next() {
myZipArray += elem
}
println(myZipArray) // [(1, a), (2, b), (3, c)]
-- UPDATE: EVEN BETTER! --
let myZip = Zip2([1, 2, 3], ["a", "b", "c"])
let myZipArray = Array(myZip)
println(myZipArray) // [(1, a), (2, b), (3, c)]
-- now for fun --
I'm going to guess that we can init a new Array with anything that responds to generate() ?
println(Array("abcde")) // [a, b, c, d, e]
Assume that vals is the result of Zip2, which I'll presume is an array of two tuples. Like this:
let vals = [(1, "a"), (2, "b"), (3, "c")]
With that, just invoke the map() method on an array.
vals.map { $0.0 }
For example:
> vals.map { $0.1 }
$R16: String[] = size=3 {
[0] = "a"
[1] = "b"
[2] = "c"
}

Array initializing in Scala

I'm new to Scala ,just started learning it today.I would like to know how to initialize an array in Scala.
Example Java code
String[] arr = { "Hello", "World" };
What is the equivalent of the above code in Scala ?
scala> val arr = Array("Hello","World")
arr: Array[java.lang.String] = Array(Hello, World)
To initialize an array filled with zeros, you can use:
> Array.fill[Byte](5)(0)
Array(0, 0, 0, 0, 0)
This is equivalent to Java's new byte[5].
Can also do more dynamic inits with fill, e.g.
Array.fill(10){scala.util.Random.nextInt(5)}
==>
Array[Int] = Array(0, 1, 0, 0, 3, 2, 4, 1, 4, 3)
Additional to Vasil's answer: If you have the values given as a Scala collection, you can write
val list = List(1,2,3,4,5)
val arr = Array[Int](list:_*)
println(arr.mkString)
But usually the toArray method is more handy:
val list = List(1,2,3,4,5)
val arr = list.toArray
println(arr.mkString)
If you know Array's length but you don't know its content, you can use
val length = 5
val temp = Array.ofDim[String](length)
If you want to have two dimensions array but you don't know its content, you can use
val row = 5
val column = 3
val temp = Array.ofDim[String](row, column)
Of course, you can change String to other type.
If you already know its content, you can use
val temp = Array("a", "b")
Another way of declaring multi-dimentional arrays:
Array.fill(4,3)("")
res3: Array[Array[String]] = Array(Array("", "", ""), Array("", "", ""),Array("", "", ""), Array("", "", ""))
[Consolidating all the answers]
Initializing 1-D Arrays
// With fixed values
val arr = Array("a", "ab", "c")
// With zero value of the type
val size = 13
val arrWithZeroVal = Array.ofDim[Int](size) //values = 0
val arrBoolWithZeroVal = Array.ofDim[Boolean](size) //values = false
// With default value
val defVal = -1
val arrWithDefVals = Array.fill[Int](size)(defVal)
//With random values
val rand = scala.util.Random
def randomNumberGen: Int = rand.nextInt(5)
val arrWithRandomVals = Array.fill[Int](size){randomNumberGen}
Initializing 2-D/3-D/n-D Arrays
// With zero value of the type
val arr3dWithZeroVal = Array.ofDim[Int](5, 4, 3)
// With default value
val defVal = -1
val arr3dWithDefVal = Array.fill[Int](5, 4, 3)(defVal)
//With random values
val arr3dWithRandomValv = Array.fill[Int](5, 4, 3){randomNumberGen}
Conclusion :
Use Array.ofDim[TYPE](d1, d2, d3...) to use zero value of the type.
Use Array.fill[TYPE](d1, d2, d3...)(functionWhichReturnsTYPE) otherwise
Output for reference :
scala> val arr = Array("a", "ab", "c")
arr: Array[String] = Array(a, ab, c)
scala> val size = 13
size: Int = 13
scala> val arrWithZeroVal = Array.ofDim[Int](size) //values = 0
arrWithZeroVal: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
scala> val arrBoolWithZeroVal = Array.ofDim[Boolean](size) //values = false
arrBoolWithZeroVal: Array[Boolean] = Array(false, false, false, false, false, false, false, false, false, false, false, false, false)
scala> val defVal = -1
defVal: Int = -1
scala> val arrWithDefVals = Array.fill[Int](size)(defVal)
arrWithDefVals: Array[Int] = Array(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
scala> val rand = scala.util.Random
rand: util.Random.type = scala.util.Random$#6e3dd5ce
scala> def randomNumberGen: Int = rand.nextInt(5)
randomNumberGen: Int
scala> val arrWithRandomVals = Array.fill[Int](size){randomNumberGen}
arrWithRandomVals: Array[Int] = Array(2, 2, 3, 1, 1, 3, 3, 3, 2, 3, 2, 2, 0)
scala> val arr3dWithZeroVal = Array.ofDim[Int](5, 4, 3)
arr3dWithZeroVal: Array[Array[Array[Int]]] = Array(Array(Array(0, 0, 0), Array(0, 0, 0), Array(0, 0, 0), Array(0, 0, 0)), Array(Array(0, 0, 0), Array(0, 0, 0), Array(0, 0, 0), Array(0, 0, 0)), Array(Array(0, 0, 0), Array(0, 0, 0), Array(0, 0, 0), Array(0, 0, 0)), Array(Array(0, 0, 0), Array(0, 0, 0), Array(0, 0, 0), Array(0, 0, 0)), Array(Array(0, 0, 0), Array(0, 0, 0), Array(0, 0, 0), Array(0, 0, 0)))
scala> val arr3dWithDefVal = Array.fill[Int](5, 4, 3)(defVal)
arr3dWithDefVal: Array[Array[Array[Int]]] = Array(Array(Array(-1, -1, -1), Array(-1, -1, -1), Array(-1, -1, -1), Array(-1, -1, -1)), Array(Array(-1, -1, -1), Array(-1, -1, -1), Array(-1, -1, -1), Array(-1, -1, -1)), Array(Array(-1, -1, -1), Array(-1, -1, -1), Array(-1, -1, -1), Array(-1, -1, -1)), Array(Array(-1, -1, -1), Array(-1, -1, -1), Array(-1, -1, -1), Array(-1, -1, -1)), Array(Array(-1, -1, -1), Array(-1, -1, -1), Array(-1, -1, -1), Array(-1, -1, -1)))
scala> val arr3dWithRandomVals = Array.fill[Int](5, 4, 3){randomNumberGen}
arr3dWithRandomVals: Array[Array[Array[Int]]] = Array(Array(Array(2, 0, 0), Array(4, 1, 0), Array(4, 0, 0), Array(0, 0, 1)), Array(Array(0, 1, 2), Array(2, 0, 2), Array(0, 4, 2), Array(0, 4, 2)), Array(Array(4, 3, 0), Array(2, 2, 4), Array(4, 0, 4), Array(4, 2, 1)), Array(Array(0, 3, 3), Array(0, 0, 4), Array(4, 1, 3), Array(2, 2, 3)), Array(Array(0, 2, 3), Array(1, 4, 1), Array(1, 3, 3), Array(0, 0, 3)))