In this vignette we will introduce some theory behind using layouts for table creation. Much of the theory also holds true when using
For this vignette we will use the following packages:
library(dplyr)
library(tibble)
library(rtables)The data we use is the following one created with random number generators:
add_subgroup <- function(x) paste0(tolower(x), sample(1:3, length(x), TRUE))
set.seed(1)
df <- tibble(
  x = rnorm(100),
  c1 = factor(sample(c("A", "B", "C"), 100, replace = TRUE), levels = c("A", "B", "C")),
  r1 = factor(sample(c("U", "V", "W"), 100, replace = TRUE), levels = c("U", "V", "W"))
) %>%
  mutate(
    c2 = add_subgroup(c1),
    r2 = add_subgroup(r1),
    y = as.numeric(2*as.numeric(c1) - 3 * as.numeric(r1))
  ) %>% select(c1, c2, r1, r2, x, y)
df# A tibble: 100 × 6
   c1    c2    r1    r2         x     y
   <fct> <chr> <fct> <chr>  <dbl> <dbl>
 1 B     b2    U     u3    -0.626     1
 2 A     a3    V     v2     0.184    -4
 3 B     b1    V     v2    -0.836    -2
 4 B     b3    V     v2     1.60     -2
 5 B     b1    U     u1     0.330     1
 6 C     c1    U     u3    -0.820     3
 7 A     a3    U     u3     0.487    -1
 8 B     b1    U     u3     0.738     1
 9 C     c3    V     v2     0.576     0
10 C     c3    U     u2    -0.305     3
# … with 90 more rowsLet’s look at a table that has 3 columns and 3 rows. Each row represents a different analysis (functions foo, bar, zoo that return an rcell object):
                     A         B         C
------------------------------------------------
foo_label        foo(df_A)  foo(df_B)  foo(df_C)
bar_label        bar(df_A)  bar(df_B)  bar(df_C)
zoo_label        zoo(df_A)  zoo(df_B)  zoo(df_C)The data passed to the analysis functions are a subset defined by the respective column and:
df_A <- df %>% filter(c1 == "A")
df_B <- df %>% filter(c1 == "B")
df_C <- df %>% filter(c1 == "C")Let’s do this on the concrete data with analyze:
foo <- prod
bar <- sum
zoo <- mean
basic_table() %>%
  split_cols_by("c1") %>%
  analyze("x", function(df) foo(df$x), var_labels = "foo label", format = "xx.xx") %>%
  analyze("x", function(df) bar(df$x), var_labels = "bar label", format = "xx.xx") %>%
  analyze("x", function(df) zoo(df$x), var_labels = "zoo label", format = "xx.xx") %>%
  build_table(df)Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.               A       B       C  
——————————————————————————————————
foo label                         
  foo label   0.00   -0.00   -0.00
bar label                         
  bar label   1.87   4.37    4.64 
zoo label                         
  zoo label   0.05   0.13    0.18 of if we wanted the x variable instead of the data frame:
                     A         B         C
------------------------------------------------
foo_label        foo(x_A)  foo(x_B)  foo(x_C)
bar_label        bar(x_A)  bar(x_B)  bar(x_C)
zoo_label        zoo(x_A)  zoo(x_B)  zoo(x_C)where
x_A <- df_A$x
x_B <- df_B$x
x_C <- df_C$xThe function passed to afun is evaluated using argument matching, if afun has an argument x the analysis variable specified in vars in analyze is passed to the function and if afun has an argument df then set subset of the dataset is passed to afun. So,
basic_table() %>%
  split_cols_by("c1") %>%
  analyze("x", foo, var_labels = "foo label", format = "xx.xx") %>%
  analyze("x", bar, var_labels = "bar label", format = "xx.xx") %>%
  analyze("x", zoo, var_labels = "zoo label", format = "xx.xx") %>%
  build_table(df)Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.             A       B       C  
————————————————————————————————
foo label                       
  foo       0.00   -0.00   -0.00
bar label                       
  bar       1.87   4.37    4.64 
zoo label                       
  zoo       0.05   0.13    0.18 Note that it is also possible that a function returns multiple rows with in_rows
basic_table() %>%
  split_cols_by("c1") %>%
  analyze("x", function(x) {
    in_rows(
      "row 1" = rcell(mean(x), format = "xx.xx"),
      "row 2" = rcell(sd(x), format = "xx.xxx")
    )
  }, var_labels = "foo label") %>%
  analyze("x", function(x) {
    in_rows(
      "more rows 1" =  rcell(median(x), format = "xx.x"),
      "even more rows 1" = rcell(IQR(x), format = "xx.xx")
    )
  }, var_labels = "bar label", format = "xx.xx") %>%
  build_table(df)Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.                       A       B       C  
——————————————————————————————————————————
foo label                                 
  row 1              0.05    0.13    0.18 
  row 2              0.985   0.815   0.890
bar label                                 
  more rows 1        -0.0     0.2     0.3 
  even more rows 1   1.20    1.15    1.16 which is how we recommend to specify the row names explicitly.
Let’s say we would like to create the following table:
            A         B         C
--------------------------------------
U        foo(df_UA)  foo(df_UB)  foo(df_UC)
V        foo(df_VA)  foo(df_VB)  foo(df_VC)
W        foo(df_WA)  foo(df_WB)  foo(df_WC)where df_* are subsets of df as follows:
df_UA <- df %>% filter(r1 == "U", c1 == "A")
df_VA <- df %>% filter(r1 == "V", c1 == "A")
df_WA <- df %>% filter(r1 == "W", c1 == "A")
df_UB <- df %>% filter(r1 == "U", c1 == "B")
df_VB <- df %>% filter(r1 == "V", c1 == "B")
df_WB <- df %>% filter(r1 == "W", c1 == "C")
df_UC <- df %>% filter(r1 == "U", c1 == "C")
df_VC <- df %>% filter(r1 == "V", c1 == "C")
df_WC <- df %>% filter(r1 == "W", c1 == "C")further note that df_* are of the same class as df, i.e. tibbles. Hence foo aggregates the subset of our data to a cell value.
Given a function foo (ignore the ... for now):
foo <- function(df, labelstr = "", ...) {
  paste(dim(df), collapse = " x ")
}we can start calculating the cell values individually:
foo(df_UA)[1] "17 x 6"foo(df_VA)[1] "9 x 6"foo(df_WA)[1] "14 x 6"foo(df_UB)[1] "13 x 6"foo(df_VB)[1] "15 x 6"foo(df_WB)[1] "11 x 6"foo(df_UC)[1] "10 x 6"foo(df_VC)[1] "5 x 6"foo(df_WC)[1] "11 x 6"Now we are still missing the table structure:
matrix(
  list(
    foo(df_UA),
    foo(df_VA),
    foo(df_WA),
    foo(df_UB),
    foo(df_VB),
    foo(df_WB),
    foo(df_UC),
    foo(df_VC),
    foo(df_WC)
  ), 
  byrow = FALSE, ncol = 3
)     [,1]     [,2]     [,3]    
[1,] "17 x 6" "13 x 6" "10 x 6"
[2,] "9 x 6"  "15 x 6" "5 x 6" 
[3,] "14 x 6" "11 x 6" "11 x 6"In rtables this type of tabulation is done with layouts
basic_table() %>%
  split_cols_by("c1") %>%
  split_rows_by("r1") %>%
  analyze("x", foo) %>%
  build_table(df)          A        B        C   
————————————————————————————————
U                               
  foo   17 x 6   13 x 6   10 x 6
V                               
  foo   9 x 6    15 x 6   5 x 6 
W                               
  foo   14 x 6   6 x 6    11 x 6or if we would not want to see the foo label we would have to use
basic_table() %>%
  split_cols_by("c1") %>%
  split_rows_by("r1") %>%
  summarize_row_groups(cfun = foo, format = "xx") %>%
  build_table(df)     A        B        C   
———————————————————————————
   17 x 6   13 x 6   10 x 6
   9 x 6    15 x 6   5 x 6 
   14 x 6   6 x 6    11 x 6but now the row labels disapered. This is because cfun needs to define it’s row label. So let’s redefine foo:
foo <- function(df, labelstr) {
  rcell(paste(dim(df), collapse = " x "), format = "xx", label = labelstr)
}
basic_table() %>%
  split_cols_by("c1") %>%
  split_rows_by("r1") %>%
  summarize_row_groups(cfun = foo) %>%
  build_table(df)      A        B        C   
————————————————————————————
U   17 x 6   13 x 6   10 x 6
V   9 x 6    15 x 6   5 x 6 
W   14 x 6   6 x 6    11 x 6For lets calculate the mean of df$y for pattern I.
foo <- function(df, labelstr) {
  rcell(mean(df$y), label = labelstr, format = "xx.xx")
}
basic_table() %>%
  split_cols_by("c1") %>%
  split_rows_by("r1") %>%
  summarize_row_groups(cfun = foo) %>%
  build_table(df)      A       B       C  
—————————————————————————
U   -1.00   1.00    3.00 
V   -4.00   -2.00   0.00 
W   -7.00   -5.00   -3.00Note that foo has the variable information hard encoded in the function body. Let’s try some alternatives returning to analyze:
basic_table() %>%
  split_cols_by("c1") %>%
  split_rows_by("r1") %>%
  analyze("y", afun = mean) %>%
  build_table(df)         A    B    C 
—————————————————————
U                    
  mean   -1   1    3 
V                    
  mean   -4   -2   0 
W                    
  mean   -7   -5   -3note that the subset of the y variable is passed as x argument to mean. We could also get the data.frame instead of the variable:
basic_table() %>%
  split_cols_by("c1") %>%
  split_rows_by("r1") %>%
  analyze("y", afun = function(df) mean(df$y)) %>%
  build_table(df)      A    B    C 
——————————————————
U                 
  y   -1   1    3 
V                 
  y   -4   -2   0 
W                 
  y   -7   -5   -3which is in contrast to:
basic_table() %>%
  split_cols_by("c1") %>%
  split_rows_by("r1") %>%
  analyze("y", afun = function(x) mean(x)) %>%
  build_table(df)      A    B    C 
——————————————————
U                 
  y   -1   1    3 
V                 
  y   -4   -2   0 
W                 
  y   -7   -5   -3where the function receives the subset of y.
Pattern I is an interesting one as we can add more row structure (with further splits). Consider the following table:
            A         B         C
--------------------------------------
U        
  u1     foo(<>)  foo(<>)  foo(<>)
  u2     foo(<>)  foo(<>)  foo(<>)
  u3     foo(<>)  foo(<>)  foo(<>)
V 
  v1     foo(<>)  foo(<>)  foo(<>)
  v2     foo(<>)  foo(<>)  foo(<>)
  v3     foo(<>)  foo(<>)  foo(<>)
W
  w1     foo(<>)  foo(<>)  foo(<>)
  w2     foo(<>)  foo(<>)  foo(<>)
  w3     foo(<>)  foo(<>)  foo(<>)where <> represents the data that is represented by the cell. So for the cell U > u1, A we would have the subset:
df %>% 
  filter(r1 == "U", r2 == "u1", c1 == "A")# A tibble: 2 × 6
  c1    c2    r1    r2        x     y
  <fct> <chr> <fct> <chr> <dbl> <dbl>
1 A     a2    U     u1    1.12     -1
2 A     a1    U     u1    0.594    -1and so on. We can get this table as follows:
basic_table() %>%
  split_cols_by("c1") %>%
  split_rows_by("r1") %>%
  split_rows_by("r2") %>%
  summarize_row_groups(cfun = function(df, labelstr) {
    rcell(mean(df$x), format = "xx.xx", label = paste("mean x for", labelstr))
  }) %>% 
  build_table(df)                    A       B       C  
———————————————————————————————————————
U                                      
  mean x for u3   -0.04   0.36    -0.25
  mean x for u1   0.86    0.32     NA  
  mean x for u2   -0.28   0.38    0.08 
V                                      
  mean x for v2   0.01    0.55    0.60 
  mean x for v3   -0.03   -0.30   1.06 
  mean x for v1   0.56    -0.27   -0.54
W                                      
  mean x for w1   -0.58   0.42    0.67 
  mean x for w3   0.56    0.69    -0.39
  mean x for w2   -1.99   -0.10   0.53 or, if we wanted to calculate two summaries per row split:
s_mean_sd <- function(x) {
  in_rows("mean (sd)" = rcell(c(mean(x), sd(x)), format = "xx.xx (xx.xx)"))
}
s_range <- function(x) {
  in_rows("range" = rcell(range(x), format = "xx.xx - xx.xx"))
}
basic_table() %>%
  split_cols_by("c1") %>%
  split_rows_by("r1") %>%
  split_rows_by("r2") %>%
  analyze("x", s_mean_sd, show_labels = "hidden") %>%
  analyze("x", s_range, show_labels = "hidden") %>%
  build_table(df)Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.Warning in min(x): no non-missing arguments to min; returning InfWarning in max(x): no non-missing arguments to max; returning -InfWarning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.
Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.
Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.
Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.
Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.
Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.
Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.
Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.                      A              B              C      
———————————————————————————————————————————————————————————
U                                                          
  u3                                                       
    mean (sd)   -0.04 (1.18)    0.36 (1.41)    -0.25 (0.72)
    range       -1.80 - 1.47    -1.28 - 2.40   -0.82 - 0.56
  u1                                                       
    mean (sd)    0.86 (0.38)    0.32 (0.51)      NA (NA)   
    range        0.59 - 1.12    -0.48 - 0.94    Inf - -Inf 
  u2                                                       
    mean (sd)   -0.28 (0.96)    0.38 (0.67)    0.08 (0.91) 
    range       -1.52 - 1.43    -0.39 - 0.82   -0.93 - 1.51
V                                                          
  v2                                                       
    mean (sd)    0.01 (0.25)    0.55 (1.14)    0.60 (0.03) 
    range       -0.16 - 0.18    -0.84 - 1.60   0.58 - 0.62 
  v3                                                       
    mean (sd)   -0.03 (0.37)    -0.30 (0.36)    1.06 (NA)  
    range       -0.41 - 0.33    -0.62 - 0.03   1.06 - 1.06 
  v1                                                       
    mean (sd)    0.56 (1.10)    -0.27 (0.73)   -0.54 (1.18)
    range       -0.16 - 2.17    -1.22 - 0.59   -1.38 - 0.29
W                                                          
  w1                                                       
    mean (sd)   -0.58 (0.85)     0.42 (NA)     0.67 (0.39) 
    range       -1.25 - 0.61    0.42 - 0.42    0.37 - 1.21 
  w3                                                       
    mean (sd)    0.56 (0.85)     0.69 (NA)     -0.39 (1.68)
    range       -0.71 - 1.98    0.69 - 0.69    -2.21 - 1.10
  w2                                                       
    mean (sd)    -1.99 (NA)     -0.10 (0.47)   0.53 (0.60) 
    range       -1.99 - -1.99   -0.61 - 0.39   -0.10 - 1.16Which has the following structure:
                   A              B              C
---------------------------------------------------------
U        
  u1
     mean_sd  s_mean_sd(<>)  s_mean_sd(<>)  s_mean_sd(<>)
     range    s_range(<>)    s_range(<>)    s_range(<>)
  u2
     mean_sd  s_mean_sd(<>)  s_mean_sd(<>)  s_mean_sd(<>)
     range    s_range(<>)    s_range(<>)    s_range(<>)
  u3
     mean_sd  s_mean_sd(<>)  s_mean_sd(<>)  s_mean_sd(<>)
     range    s_range(<>)    s_range(<>)    s_range(<>)
V 
  v1
     mean_sd  s_mean_sd(<>)  s_mean_sd(<>)  s_mean_sd(<>)
     range    s_range(<>)    s_range(<>)    s_range(<>)
  v2
     mean_sd  s_mean_sd(<>)  s_mean_sd(<>)  s_mean_sd(<>)
     range    s_range(<>)    s_range(<>)    s_range(<>)
  v3
     mean_sd  s_mean_sd(<>)  s_mean_sd(<>)  s_mean_sd(<>)
     range    s_range(<>)    s_range(<>)    s_range(<>)
W
  w1
     mean_sd  s_mean_sd(<>)  s_mean_sd(<>)  s_mean_sd(<>)
     range    s_range(<>)    s_range(<>)    s_range(<>)
  w2
     mean_sd  s_mean_sd(<>)  s_mean_sd(<>)  s_mean_sd(<>)
     range    s_range(<>)    s_range(<>)    s_range(<>)
  w3
     mean_sd  s_mean_sd(<>)  s_mean_sd(<>)  s_mean_sd(<>)
     range    s_range(<>)    s_range(<>)    s_range(<>)The rows U, u1, u2, …, W, w1, w2, w3 are label rows and the other rows (with mean_sd and range are data rows). Currently we do not have content rows in the table. Content rows summarize the data defined by their splitting (i.e. V > v1, B). So if we wanted to add content row at the r2 split level then we would get:
                   A              B              C
---------------------------------------------------------
U        
  u1          s_cfun_2(<>)   s_cfun_2(<>)   s_cfun_2(<>)
     mean_sd  s_mean_sd(<>)  s_mean_sd(<>)  s_mean_sd(<>)
     range    s_range(<>)    s_range(<>)    s_range(<>)
  u2          s_cfun_2(<>)   s_cfun_2(<>)   s_cfun_2(<>)
     mean_sd  s_mean_sd(<>)  s_mean_sd(<>)  s_mean_sd(<>)
     range    s_range(<>)    s_range(<>)    s_range(<>)
  u3          s_cfun_2(<>)   s_cfun_2(<>)   s_cfun_2(<>)
     mean_sd  s_mean_sd(<>)  s_mean_sd(<>)  s_mean_sd(<>)
     range    s_range(<>)    s_range(<>)    s_range(<>)
V 
  v1          s_cfun_2(<>)   s_cfun_2(<>)   s_cfun_2(<>)
     mean_sd  s_mean_sd(<>)  s_mean_sd(<>)  s_mean_sd(<>)
     range    s_range(<>)    s_range(<>)    s_range(<>)
  v2          s_cfun_2(<>)   s_cfun_2(<>)   s_cfun_2(<>)
     mean_sd  s_mean_sd(<>)  s_mean_sd(<>)  s_mean_sd(<>)
     range    s_range(<>)    s_range(<>)    s_range(<>)
  v3          s_cfun_2(<>)   s_cfun_2(<>)   s_cfun_2(<>)
     mean_sd  s_mean_sd(<>)  s_mean_sd(<>)  s_mean_sd(<>)
     range    s_range(<>)    s_range(<>)    s_range(<>)
W
  w1          s_cfun_2(<>)   s_cfun_2(<>)   s_cfun_2(<>)
     mean_sd  s_mean_sd(<>)  s_mean_sd(<>)  s_mean_sd(<>)
     range    s_range(<>)    s_range(<>)    s_range(<>)
  w2          s_cfun_2(<>)   s_cfun_2(<>)   s_cfun_2(<>)
     mean_sd  s_mean_sd(<>)  s_mean_sd(<>)  s_mean_sd(<>)
     range    s_range(<>)    s_range(<>)    s_range(<>)
  w3          s_cfun_2(<>)   s_cfun_2(<>)   s_cfun_2(<>)
     mean_sd  s_mean_sd(<>)  s_mean_sd(<>)  s_mean_sd(<>)
     range    s_range(<>)    s_range(<>)    s_range(<>)where s_cfun_2 is the content function and either returns one row via rcell or multiple rows via in_rows. The data represented by <> for the content rows is same data as for it’s descendant, i.e. for the U > u1, A content row cell it is df %>% filter(r1 == "U", r2 == "u1", c1 == "A"). Note that content functions cfun operate only on data frames and not on vectors/variables so they must take the df argument. Further, a cfun must also have the labelstr argument which is the split level. This way, the cfun can define its own row name. In order to get the table above we can use the layout framework as follows:
s_mean_sd <- function(x) {
  in_rows("mean (sd)" = rcell(c(mean(x), sd(x)), format = "xx.xx (xx.xx)"))
}
s_range <- function(x) {
  in_rows("range" = rcell(range(x), format = "xx.xx - xx.xx"))
}
s_cfun_2 <- function(df, labelstr) {
  rcell(nrow(df), format = "xx", label = paste(labelstr, "(n)"))
}
basic_table() %>%
  split_cols_by("c1") %>%
  split_rows_by("r1") %>%
  split_rows_by("r2") %>%
  summarize_row_groups(cfun = s_cfun_2) %>%
  analyze("x", s_mean_sd, show_labels = "hidden") %>%
  analyze("x", s_range, show_labels = "hidden") %>%
  build_table(df)Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.Warning in min(x): no non-missing arguments to min; returning InfWarning in max(x): no non-missing arguments to max; returning -InfWarning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.
Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.
Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.
Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.
Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.
Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.
Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.
Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.                      A              B              C      
———————————————————————————————————————————————————————————
U                                                          
  u3 (n)              6              5              3      
    mean (sd)   -0.04 (1.18)    0.36 (1.41)    -0.25 (0.72)
    range       -1.80 - 1.47    -1.28 - 2.40   -0.82 - 0.56
  u1 (n)              2              5              0      
    mean (sd)    0.86 (0.38)    0.32 (0.51)      NA (NA)   
    range        0.59 - 1.12    -0.48 - 0.94    Inf - -Inf 
  u2 (n)              9              3              7      
    mean (sd)   -0.28 (0.96)    0.38 (0.67)    0.08 (0.91) 
    range       -1.52 - 1.43    -0.39 - 0.82   -0.93 - 1.51
V                                                          
  v2 (n)              2              4              2      
    mean (sd)    0.01 (0.25)    0.55 (1.14)    0.60 (0.03) 
    range       -0.16 - 0.18    -0.84 - 1.60   0.58 - 0.62 
  v3 (n)              3              4              1      
    mean (sd)   -0.03 (0.37)    -0.30 (0.36)    1.06 (NA)  
    range       -0.41 - 0.33    -0.62 - 0.03   1.06 - 1.06 
  v1 (n)              4              7              2      
    mean (sd)    0.56 (1.10)    -0.27 (0.73)   -0.54 (1.18)
    range       -0.16 - 2.17    -1.22 - 0.59   -1.38 - 0.29
W                                                          
  w1 (n)              4              1              4      
    mean (sd)   -0.58 (0.85)     0.42 (NA)     0.67 (0.39) 
    range       -1.25 - 0.61    0.42 - 0.42    0.37 - 1.21 
  w3 (n)              9              1              3      
    mean (sd)    0.56 (0.85)     0.69 (NA)     -0.39 (1.68)
    range       -0.71 - 1.98    0.69 - 0.69    -2.21 - 1.10
  w2 (n)              1              4              4      
    mean (sd)    -1.99 (NA)     -0.10 (0.47)   0.53 (0.60) 
    range       -1.99 - -1.99   -0.61 - 0.39   -0.10 - 1.16In the same manner, if we wanted content rows for r1 split we can do it at as follows:
basic_table() %>%
  split_cols_by("c1") %>%
  split_rows_by("r1") %>%
  summarize_row_groups(cfun = s_cfun_2) %>%
  split_rows_by("r2") %>%
  summarize_row_groups(cfun = s_cfun_2) %>%
  analyze("x", s_mean_sd, show_labels = "hidden") %>%
  analyze("x", s_range, show_labels = "hidden") %>%
  build_table(df)Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.Warning in min(x): no non-missing arguments to min; returning InfWarning in max(x): no non-missing arguments to max; returning -InfWarning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.
Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.
Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.
Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.
Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.
Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.
Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.
Warning in .make_split_kids(spl = spl, df = df, lvl = lvl, splvec = splvec, :
Non-unique sibling analysis table names. Using Labels instead. Use the
table_names argument to analyze to avoid this when analyzing the same variable
multiple times.                      A              B              C      
———————————————————————————————————————————————————————————
U (n)                17              13             10     
  u3 (n)              6              5              3      
    mean (sd)   -0.04 (1.18)    0.36 (1.41)    -0.25 (0.72)
    range       -1.80 - 1.47    -1.28 - 2.40   -0.82 - 0.56
  u1 (n)              2              5              0      
    mean (sd)    0.86 (0.38)    0.32 (0.51)      NA (NA)   
    range        0.59 - 1.12    -0.48 - 0.94    Inf - -Inf 
  u2 (n)              9              3              7      
    mean (sd)   -0.28 (0.96)    0.38 (0.67)    0.08 (0.91) 
    range       -1.52 - 1.43    -0.39 - 0.82   -0.93 - 1.51
V (n)                 9              15             5      
  v2 (n)              2              4              2      
    mean (sd)    0.01 (0.25)    0.55 (1.14)    0.60 (0.03) 
    range       -0.16 - 0.18    -0.84 - 1.60   0.58 - 0.62 
  v3 (n)              3              4              1      
    mean (sd)   -0.03 (0.37)    -0.30 (0.36)    1.06 (NA)  
    range       -0.41 - 0.33    -0.62 - 0.03   1.06 - 1.06 
  v1 (n)              4              7              2      
    mean (sd)    0.56 (1.10)    -0.27 (0.73)   -0.54 (1.18)
    range       -0.16 - 2.17    -1.22 - 0.59   -1.38 - 0.29
W (n)                14              6              11     
  w1 (n)              4              1              4      
    mean (sd)   -0.58 (0.85)     0.42 (NA)     0.67 (0.39) 
    range       -1.25 - 0.61    0.42 - 0.42    0.37 - 1.21 
  w3 (n)              9              1              3      
    mean (sd)    0.56 (0.85)     0.69 (NA)     -0.39 (1.68)
    range       -0.71 - 1.98    0.69 - 0.69    -2.21 - 1.10
  w2 (n)              1              4              4      
    mean (sd)    -1.99 (NA)     -0.10 (0.47)   0.53 (0.60) 
    range       -1.99 - -1.99   -0.61 - 0.39   -0.10 - 1.16In pagination content rows and label rows get repeated if a page is split in a descendant of a content row. So for example, if we were to split the following table at *** then :
                   A              B              C
---------------------------------------------------------
U        
  u1 (n)      s_cfun_2(<>)   s_cfun_2(<>)   s_cfun_2(<>)
     mean_sd  s_mean_sd(<>)  s_mean_sd(<>)  s_mean_sd(<>)
***
     range    s_range(<>)    s_range(<>)    s_range(<>)
  u2 (n)      s_cfun_2(<>)   s_cfun_2(<>)   s_cfun_2(<>)
     mean_sd  s_mean_sd(<>)  s_mean_sd(<>)  s_mean_sd(<>)
     range    s_range(<>)    s_range(<>)    s_range(<>)we would get the following two tables:
                   A              B              C
---------------------------------------------------------
U        
  u1 (n)      s_cfun_2(<>)   s_cfun_2(<>)   s_cfun_2(<>)
     mean_sd  s_mean_sd(<>)  s_mean_sd(<>)  s_mean_sd(<>)and
                   A              B              C
---------------------------------------------------------
U        
  u1 (n)      s_cfun_2(<>)   s_cfun_2(<>)   s_cfun_2(<>)
     range    s_range(<>)    s_range(<>)    s_range(<>)
  u2 (n)      s_cfun_2(<>)   s_cfun_2(<>)   s_cfun_2(<>)
     mean_sd  s_mean_sd(<>)  s_mean_sd(<>)  s_mean_sd(<>)
     range    s_range(<>)    s_range(<>)    s_range(<>)Let’s consider the following tabulation pattern:
                     A         B         C
------------------------------------------------
label 1        foo(x_A)  bar(x_B)  zoo(x_C)
label 2        foo(x_A)  bar(x_B)  zoo(x_C)
label 3        foo(x_A)  bar(x_B)  zoo(x_C)We will discuss that in a future release of rtables.