library("broadcast")
# Example 1: Basics ====
<- list(
x group1 = list(
class1 = list(
height = rnorm(10, 170),
weight = rnorm(10, 80),
sex = sample(c("M", "F", NA), 10, TRUE)
),class2 = list(
height = rnorm(10, 170),
weight = rnorm(10, 80),
sex = sample(c("M", "F", NA), 10, TRUE)
)
),group2 = list(
class1 = list(
height = rnorm(10, 170),
weight = rnorm(10, 80),
sex = sample(c("M", "F", NA), 10, TRUE)
),class2 = list(
height = rnorm(10, 170),
weight = rnorm(10, 80),
sex = sample(c("M", "F", NA), 10, TRUE)
)
)
)
# predict what dimensions `x` would have if casted as dimensional:
hier2dim(x)
##
## 3 2 2
<- cast_hier2dim(x) # cast as dimensional
x2
# since the original list uses the same names for all elements within the same depth,
# dimnames can be set easily:
dimnames(x2) <- list( # go from deep names to surface names
names( x[[1]][[1]] ),
names( x[[1]] ),
names( x )
)print(x2) # very compact, maybe too compact...?
## , , group1
##
## class1 class2
## height numeric,10 numeric,10
## weight numeric,10 numeric,10
## sex character,10 character,10
##
## , , group2
##
## class1 class2
## height numeric,10 numeric,10
## weight numeric,10 numeric,10
## sex character,10 character,10
# print a small portion of the list, but less compact:
cast_dim2flat(x2[, 1:2, "group1", drop = FALSE])
## $`['height', 'class1', 'group1']`
## [1] 170.1099 169.8669 168.6903 170.6072 170.9987 168.8542 168.5772 167.7288
## [9] 168.2776 171.6016
##
## $`['weight', 'class1', 'group1']`
## [1] 79.93538 79.69118 81.11104 80.84213 80.78658 78.63298 78.41453 78.95447
## [9] 78.74834 80.47500
##
## $`['sex', 'class1', 'group1']`
## [1] "F" "F" NA "F" "M" NA NA NA "M" "F"
##
## $`['height', 'class2', 'group1']`
## [1] 170.1941 171.0616 169.9938 169.5438 170.9754 170.1538 170.5746 170.4027
## [9] 168.9055 170.1942
##
## $`['weight', 'class2', 'group1']`
## [1] 82.17763 79.63080 80.01781 80.73256 80.00713 79.67317 79.88375 79.67042
## [9] 80.33282 80.71595
##
## $`['sex', 'class2', 'group1']`
## [1] NA NA "F" "M" "M" NA "M" "F" "F" "M"
# Example 2: Cast from outside to inside ====
<- list(
x group1 = list(
class1 = list(
height = rnorm(10, 170),
weight = rnorm(10, 80),
sex = sample(c("M", "F", NA), 10, TRUE)
),class2 = list(
height = rnorm(10, 170),
weight = rnorm(10, 80),
sex = sample(c("M", "F", NA), 10, TRUE)
)
),group2 = list(
class1 = list(
height = rnorm(10, 170),
weight = rnorm(10, 80),
sex = sample(c("M", "F", NA), 10, TRUE)
),class2 = list(
height = rnorm(10, 170),
weight = rnorm(10, 80),
sex = sample(c("M", "F", NA), 10, TRUE)
)
)
)
# by default, `in2out = TRUE`;
# for this example, `in2out = FALSE` is used
# predict what dimensions `x` would have if casted as dimensional:
hier2dim(x, in2out = FALSE)
##
## 2 2 3
<- cast_hier2dim(x, in2out = FALSE) # cast as dimensional
x2
# since the original list uses the same names for all elements within the same depth,
# dimnames can be set easily:
# because in2out = FALSE, go from the shallow names to the deeper names:
dimnames(x2) <- list(
names( x ),
names( x[[1]] ),
names( x[[1]][[1]] )
)print(x2) # very compact, maybe too compact...?
## , , height
##
## class1 class2
## group1 numeric,10 numeric,10
## group2 numeric,10 numeric,10
##
## , , weight
##
## class1 class2
## group1 numeric,10 numeric,10
## group2 numeric,10 numeric,10
##
## , , sex
##
## class1 class2
## group1 character,10 character,10
## group2 character,10 character,10
# print a small portion of the list, but less compact:
cast_dim2flat(x2["group1", 1:2, , drop = FALSE])
## $`['group1', 'class1', 'height']`
## [1] 172.0610 172.0956 169.4149 169.6854 169.2117 171.4754 170.1175 170.8357
## [9] 169.5531 171.6149
##
## $`['group1', 'class2', 'height']`
## [1] 168.6011 170.0912 170.7617 170.3002 169.9314 169.6757 170.3824 170.9417
## [9] 171.6930 170.9168
##
## $`['group1', 'class1', 'weight']`
## [1] 79.97539 79.47191 79.07884 80.96704 79.66578 81.71610 83.10435 77.29645
## [9] 78.23989 78.52771
##
## $`['group1', 'class2', 'weight']`
## [1] 78.72343 81.17115 79.25420 79.14268 77.84086 79.00341 78.86452 79.33254
## [9] 79.97067 80.65964
##
## $`['group1', 'class1', 'sex']`
## [1] NA "F" NA "F" "F" "M" "M" "F" NA NA
##
## $`['group1', 'class2', 'sex']`
## [1] "M" "F" NA "F" "F" "M" "F" "M" "F" "F"
# Example 3: padding ====
# For Example 3, take the same list as before, but remove x$group1$class2:
<- list(
x group1 = list(
class1 = list(
height = rnorm(10, 170),
weight = rnorm(10, 80),
sex = sample(c("M", "F", NA), 10, TRUE)
)
),group2 = list(
class1 = list(
height = rnorm(10, 170),
weight = rnorm(10, 80),
sex = sample(c("M", "F", NA), 10, TRUE)
),class2 = list(
height = rnorm(10, 170),
weight = rnorm(10, 80),
sex = sample(c("M", "F", NA), 10, TRUE)
)
)
)
hier2dim(x) # as indicated here, dimension 2 (i.e. columns) will have padding
## padding
## 3 2 2
# casting this to a dimensional list will resulting in padding with `NULL`:
<- cast_hier2dim(x)
x2 print(x2)
## , , 1
##
## [,1] [,2]
## [1,] numeric,10 NULL
## [2,] numeric,10 NULL
## [3,] character,10 NULL
##
## , , 2
##
## [,1] [,2]
## [1,] numeric,10 numeric,10
## [2,] numeric,10 numeric,10
## [3,] character,10 character,10
# The `NULL` values are added for padding.
# This is because all slices of the same dimension need to have the same number of elements.
# For example, all rows need to have the same number of columns.
# one can also use custom padding:
<- cast_hier2dim(x, padding = list(~ "this is padding"))
x2 print(x2)
## , , 1
##
## [,1] [,2]
## [1,] numeric,10 ~"this is padding"
## [2,] numeric,10 ~"this is padding"
## [3,] character,10 ~"this is padding"
##
## , , 2
##
## [,1] [,2]
## [1,] numeric,10 numeric,10
## [2,] numeric,10 numeric,10
## [3,] character,10 character,10
# because `x2` needs padding, there is no guarantee you can set dimnames using `x` properly:
if(requireNamespace("tinytest")) {
::expect_error(
tinytestdimnames(x2) <- list(
names( x[[1]][[1]] ),
names( x[[1]] ),
names( x )
),pattern = "length of 'dimnames' [2] not equal to array extent", # error message
fixed = TRUE
)
}## ----- PASSED : <-->
## call| tinytest::expect_error(dimnames(x2) <- list(names(x[[1]][[1]]),
## call| names(x[[1]]), names(x)), pattern = "length of 'dimnames' [2] not equal to array extent",
## call| fixed = TRUE)
# in this case I know what the dimnames should be, so I can try like so:
dimnames(x2) <- list(
c("height", "weight", "sex"),
c("class1", "class2"),
c("group1", "group2")
)
print(x2)
## , , group1
##
## class1 class2
## height numeric,10 ~"this is padding"
## weight numeric,10 ~"this is padding"
## sex character,10 ~"this is padding"
##
## , , group2
##
## class1 class2
## height numeric,10 numeric,10
## weight numeric,10 numeric,10
## sex character,10 character,10
cast_dim2flat(x2[1:2, , , drop = FALSE])
## $`['height', 'class1', 'group1']`
## [1] 169.7621 168.2053 169.9581 169.7660 170.1706 168.7582 168.8972 170.7493
## [9] 171.8347 171.1285
##
## $`['weight', 'class1', 'group1']`
## [1] 80.89889 79.31380 80.51947 78.98918 80.21596 79.74342 79.71871 78.51382
## [9] 80.34322 78.29674
##
## $`['height', 'class2', 'group1']`
## ~"this is padding"
##
## $`['weight', 'class2', 'group1']`
## ~"this is padding"
##
## $`['height', 'class1', 'group2']`
## [1] 170.9993 169.3167 170.0855 169.5274 170.0218 171.3431 171.2642 169.8710
## [9] 170.8574 169.1623
##
## $`['weight', 'class1', 'group2']`
## [1] 80.50542 78.09655 81.00322 79.81898 79.47169 79.78900 81.52075 80.31901
## [9] 79.61611 79.33717
##
## $`['height', 'class2', 'group2']`
## [1] 170.6276 169.2143 171.8280 169.3077 170.0187 170.5553 169.3965 168.1618
## [9] 171.2629 171.3817
##
## $`['weight', 'class2', 'group2']`
## [1] 82.32421 80.95346 79.04322 80.35230 80.15693 79.48999 80.71883 77.87738
## [9] 78.58584 79.13149
# we can also use in2out = FALSE:
<- cast_hier2dim(x, in2out = FALSE, padding = list(~ "this is padding"))
x2 dimnames(x2) <- list( # notice the order here is reversed, because in2out = FALSE
c("group1", "group2"),
c("class1", "class2"),
c("height", "weight", "sex")
)print(x2)
## , , height
##
## class1 class2
## group1 numeric,10 ~"this is padding"
## group2 numeric,10 numeric,10
##
## , , weight
##
## class1 class2
## group1 numeric,10 ~"this is padding"
## group2 numeric,10 numeric,10
##
## , , sex
##
## class1 class2
## group1 character,10 ~"this is padding"
## group2 character,10 character,10
cast_dim2flat(x2[, , 1:2, drop = FALSE])
## $`['group1', 'class1', 'height']`
## [1] 169.7621 168.2053 169.9581 169.7660 170.1706 168.7582 168.8972 170.7493
## [9] 171.8347 171.1285
##
## $`['group2', 'class1', 'height']`
## [1] 170.9993 169.3167 170.0855 169.5274 170.0218 171.3431 171.2642 169.8710
## [9] 170.8574 169.1623
##
## $`['group1', 'class2', 'height']`
## ~"this is padding"
##
## $`['group2', 'class2', 'height']`
## [1] 170.6276 169.2143 171.8280 169.3077 170.0187 170.5553 169.3965 168.1618
## [9] 171.2629 171.3817
##
## $`['group1', 'class1', 'weight']`
## [1] 80.89889 79.31380 80.51947 78.98918 80.21596 79.74342 79.71871 78.51382
## [9] 80.34322 78.29674
##
## $`['group2', 'class1', 'weight']`
## [1] 80.50542 78.09655 81.00322 79.81898 79.47169 79.78900 81.52075 80.31901
## [9] 79.61611 79.33717
##
## $`['group1', 'class2', 'weight']`
## ~"this is padding"
##
## $`['group2', 'class2', 'weight']`
## [1] 82.32421 80.95346 79.04322 80.35230 80.15693 79.48999 80.71883 77.87738
## [9] 78.58584 79.13149
cast_dim2flat
Cast Dimensional List into a Flattened List
Description
cast_dim2flat()
casts a dimensional list (i.e. recursive array) into a flat list (i.e. recursive vector), but with names that indicate the original dimensional positions of the elements.
Primary purpose for this function is to facilitate printing or summarizing dimensional lists.
Usage
cast_dim2flat(x, ...)
## Default S3 method:
cast_dim2flat(x, ...)
Arguments
x
|
a list |
…
|
further arguments passed to or from methods. |
Value
A flattened list, with names that indicate the original dimensional positions of the elements.