moodymudskipper / tb

IN ~PROGRESS my own take on `[.data.frame`
0 stars 0 forks source link

reshape, spread/gather, cast/melt, pivot_wider/pivot_longer #18

Closed moodymudskipper closed 4 years ago

moodymudskipper commented 4 years ago

See if our spread can be generalized, try to answer all examples from all alternative options and take a look at options.

For gather we can have a function index(..., var = "var" , value = "value") where the dots are columns or named expressions.

moodymudskipper commented 4 years ago

Below the examples of stats::reshape(), with the tb way for wide reshape :

library(tb)

#################### reshape with direction = "wide"

summary(Indometh)
#>  Subject      time            conc       
#>  1:11    Min.   :0.250   Min.   :0.0500  
#>  4:11    1st Qu.:0.750   1st Qu.:0.1100  
#>  2:11    Median :2.000   Median :0.3400  
#>  5:11    Mean   :2.886   Mean   :0.5918  
#>  6:11    3rd Qu.:5.000   3rd Qu.:0.8325  
#>  3:11    Max.   :8.000   Max.   :2.7200
Indometh2 <- as.data.frame(Indometh)
wide <- reshape(Indometh, v.names = "conc", idvar = "Subject",
                timevar = "time", direction = "wide")
wide
#>    Subject conc.0.25 conc.0.5 conc.0.75 conc.1 conc.1.25 conc.2 conc.3 conc.4
#> 1        1      1.50     0.94      0.78   0.48      0.37   0.19   0.12   0.11
#> 12       2      2.03     1.63      0.71   0.70      0.64   0.36   0.32   0.20
#> 23       3      2.72     1.49      1.16   0.80      0.80   0.39   0.22   0.12
#> 34       4      1.85     1.39      1.02   0.89      0.59   0.40   0.16   0.11
#> 45       5      2.05     1.04      0.81   0.39      0.30   0.23   0.13   0.11
#> 56       6      2.31     1.44      1.03   0.84      0.64   0.42   0.24   0.17
#>    conc.5 conc.6 conc.8
#> 1    0.08   0.07   0.05
#> 12   0.25   0.12   0.08
#> 23   0.11   0.08   0.08
#> 34   0.10   0.07   0.07
#> 45   0.08   0.10   0.06
#> 56   0.13   0.10   0.09
Indometh %tb>%
  .[`conc.{time}` = conc, .by = "Subject"]
#>   Subject conc.0.25 conc.0.5 conc.0.75 conc.1 conc.1.25 conc.2 conc.3 conc.4
#> 1       1      1.50     0.94      0.78   0.48      0.37   0.19   0.12   0.11
#> 2       2      2.03     1.63      0.71   0.70      0.64   0.36   0.32   0.20
#> 3       3      2.72     1.49      1.16   0.80      0.80   0.39   0.22   0.12
#> 4       4      1.85     1.39      1.02   0.89      0.59   0.40   0.16   0.11
#> 5       5      2.05     1.04      0.81   0.39      0.30   0.23   0.13   0.11
#> 6       6      2.31     1.44      1.03   0.84      0.64   0.42   0.24   0.17
#>   conc.5 conc.6 conc.8
#> 1   0.08   0.07   0.05
#> 2   0.25   0.12   0.08
#> 3   0.11   0.08   0.08
#> 4   0.10   0.07   0.07
#> 5   0.08   0.10   0.06
#> 6   0.13   0.10   0.09

## times need not be numeric
df <- data.frame(id = rep(1:4, rep(2,4)),
                 visit = I(rep(c("Before","After"), 4)),
                 x = rnorm(4), y = runif(4))
df
#>   id  visit           x         y
#> 1  1 Before  1.18046608 0.2087030
#> 2  1  After  1.14704964 0.3202810
#> 3  2 Before -0.03772287 0.6641860
#> 4  2  After -1.55307109 0.2563465
#> 5  3 Before  1.18046608 0.2087030
#> 6  3  After  1.14704964 0.3202810
#> 7  4 Before -0.03772287 0.6641860
#> 8  4  After -1.55307109 0.2563465
reshape(df, timevar = "visit", idvar = "id", direction = "wide")
#>   id    x.Before y.Before   x.After   y.After
#> 1  1  1.18046608 0.208703  1.147050 0.3202810
#> 3  2 -0.03772287 0.664186 -1.553071 0.2563465
#> 5  3  1.18046608 0.208703  1.147050 0.3202810
#> 7  4 -0.03772287 0.664186 -1.553071 0.2563465

#=== tb doesn't support doing this operation for multiple variable, we must repeat the
#=== code for x and y

df %tb>%
  .[`x.{visit}` = x, `y.{visit}` = y, .by = "id"]
#>   id    x.Before   x.After y.Before   y.After
#> 1  1  1.18046608  1.147050 0.208703 0.3202810
#> 2  2 -0.03772287 -1.553071 0.664186 0.2563465
#> 3  3  1.18046608  1.147050 0.208703 0.3202810
#> 4  4 -0.03772287 -1.553071 0.664186 0.2563465

## warns that y is really varying
reshape(df, timevar = "visit", idvar = "id", direction = "wide", v.names = "x")
#> Warning in reshapeWide(data, idvar = idvar, timevar = timevar, varying =
#> varying, : some constant variables (y) are really varying
#>   id        y    x.Before   x.After
#> 1  1 0.208703  1.18046608  1.147050
#> 3  2 0.664186 -0.03772287 -1.553071
#> 5  3 0.208703  1.18046608  1.147050
#> 7  4 0.664186 -0.03772287 -1.553071
#=== here reshape takes the first value of y by default, tb would nest the values
#=== of y instead in that case
#=== not doing it will nest explicitly
df %tb>%
  .[y =y, `x.{visit}` = x, .by = "id"]
#>   id                    y    x.Before   x.After
#> 1  1   0.208703, 0.320281  1.18046608  1.147050
#> 2  2 0.6641860, 0.2563465 -0.03772287 -1.553071
#> 3  3   0.208703, 0.320281  1.18046608  1.147050
#> 4  4 0.6641860, 0.2563465 -0.03772287 -1.553071
#=== we can choose the first y if we want though!
df %tb>%
  .[y =y[1], `x.{visit}` = x, .by = "id"]
#>   id        y    x.Before   x.After
#> 1  1 0.208703  1.18046608  1.147050
#> 2  2 0.664186 -0.03772287 -1.553071
#> 3  3 0.208703  1.18046608  1.147050
#> 4  4 0.664186 -0.03772287 -1.553071

##  unbalanced 'long' data leads to NA fill in 'wide' form
df2 <- df[1:7, ]
df2
#>   id  visit           x         y
#> 1  1 Before  1.18046608 0.2087030
#> 2  1  After  1.14704964 0.3202810
#> 3  2 Before -0.03772287 0.6641860
#> 4  2  After -1.55307109 0.2563465
#> 5  3 Before  1.18046608 0.2087030
#> 6  3  After  1.14704964 0.3202810
#> 7  4 Before -0.03772287 0.6641860
reshape(df2, timevar = "visit", idvar = "id", direction = "wide")
#>   id    x.Before y.Before   x.After   y.After
#> 1  1  1.18046608 0.208703  1.147050 0.3202810
#> 3  2 -0.03772287 0.664186 -1.553071 0.2563465
#> 5  3  1.18046608 0.208703  1.147050 0.3202810
#> 7  4 -0.03772287 0.664186        NA        NA
#=== tb behaves the same
df2 %tb>%
  .[`x.{visit}` = x, `y.{visit}` = y, .by = "id"]
#>   id    x.Before   x.After y.Before   y.After
#> 1  1  1.18046608  1.147050 0.208703 0.3202810
#> 2  2 -0.03772287 -1.553071 0.664186 0.2563465
#> 3  3  1.18046608  1.147050 0.208703 0.3202810
#> 4  4 -0.03772287        NA 0.664186        NA

## an example that isn't longitudinal data
state.x77 <- as.data.frame(state.x77)
long <- reshape(state.x77, idvar = "state", ids = row.names(state.x77),
                times = names(state.x77), timevar = "Characteristic",
                varying = list(names(state.x77)), direction = "long")
reshape(long, direction = "wide")
#>                                    state Population Income Illiteracy Life Exp
#> Alabama.Population               Alabama       3615   3624        2.1    69.05
#> Alaska.Population                 Alaska        365   6315        1.5    69.31
#> Arizona.Population               Arizona       2212   4530        1.8    70.55
#> Arkansas.Population             Arkansas       2110   3378        1.9    70.66
#> California.Population         California      21198   5114        1.1    71.71
#> Colorado.Population             Colorado       2541   4884        0.7    72.06
#> Connecticut.Population       Connecticut       3100   5348        1.1    72.48
#> Delaware.Population             Delaware        579   4809        0.9    70.06
#> Florida.Population               Florida       8277   4815        1.3    70.66
#> Georgia.Population               Georgia       4931   4091        2.0    68.54
#> Hawaii.Population                 Hawaii        868   4963        1.9    73.60
#> Idaho.Population                   Idaho        813   4119        0.6    71.87
#> Illinois.Population             Illinois      11197   5107        0.9    70.14
#> Indiana.Population               Indiana       5313   4458        0.7    70.88
#> Iowa.Population                     Iowa       2861   4628        0.5    72.56
#> Kansas.Population                 Kansas       2280   4669        0.6    72.58
#> Kentucky.Population             Kentucky       3387   3712        1.6    70.10
#> Louisiana.Population           Louisiana       3806   3545        2.8    68.76
#> Maine.Population                   Maine       1058   3694        0.7    70.39
#> Maryland.Population             Maryland       4122   5299        0.9    70.22
#> Massachusetts.Population   Massachusetts       5814   4755        1.1    71.83
#> Michigan.Population             Michigan       9111   4751        0.9    70.63
#> Minnesota.Population           Minnesota       3921   4675        0.6    72.96
#> Mississippi.Population       Mississippi       2341   3098        2.4    68.09
#> Missouri.Population             Missouri       4767   4254        0.8    70.69
#> Montana.Population               Montana        746   4347        0.6    70.56
#> Nebraska.Population             Nebraska       1544   4508        0.6    72.60
#> Nevada.Population                 Nevada        590   5149        0.5    69.03
#> New Hampshire.Population   New Hampshire        812   4281        0.7    71.23
#> New Jersey.Population         New Jersey       7333   5237        1.1    70.93
#> New Mexico.Population         New Mexico       1144   3601        2.2    70.32
#> New York.Population             New York      18076   4903        1.4    70.55
#> North Carolina.Population North Carolina       5441   3875        1.8    69.21
#> North Dakota.Population     North Dakota        637   5087        0.8    72.78
#> Ohio.Population                     Ohio      10735   4561        0.8    70.82
#> Oklahoma.Population             Oklahoma       2715   3983        1.1    71.42
#> Oregon.Population                 Oregon       2284   4660        0.6    72.13
#> Pennsylvania.Population     Pennsylvania      11860   4449        1.0    70.43
#> Rhode Island.Population     Rhode Island        931   4558        1.3    71.90
#> South Carolina.Population South Carolina       2816   3635        2.3    67.96
#> South Dakota.Population     South Dakota        681   4167        0.5    72.08
#> Tennessee.Population           Tennessee       4173   3821        1.7    70.11
#> Texas.Population                   Texas      12237   4188        2.2    70.90
#> Utah.Population                     Utah       1203   4022        0.6    72.90
#> Vermont.Population               Vermont        472   3907        0.6    71.64
#> Virginia.Population             Virginia       4981   4701        1.4    70.08
#> Washington.Population         Washington       3559   4864        0.6    71.72
#> West Virginia.Population   West Virginia       1799   3617        1.4    69.48
#> Wisconsin.Population           Wisconsin       4589   4468        0.7    72.48
#> Wyoming.Population               Wyoming        376   4566        0.6    70.29
#>                           Murder HS Grad Frost   Area
#> Alabama.Population          15.1    41.3    20  50708
#> Alaska.Population           11.3    66.7   152 566432
#> Arizona.Population           7.8    58.1    15 113417
#> Arkansas.Population         10.1    39.9    65  51945
#> California.Population       10.3    62.6    20 156361
#> Colorado.Population          6.8    63.9   166 103766
#> Connecticut.Population       3.1    56.0   139   4862
#> Delaware.Population          6.2    54.6   103   1982
#> Florida.Population          10.7    52.6    11  54090
#> Georgia.Population          13.9    40.6    60  58073
#> Hawaii.Population            6.2    61.9     0   6425
#> Idaho.Population             5.3    59.5   126  82677
#> Illinois.Population         10.3    52.6   127  55748
#> Indiana.Population           7.1    52.9   122  36097
#> Iowa.Population              2.3    59.0   140  55941
#> Kansas.Population            4.5    59.9   114  81787
#> Kentucky.Population         10.6    38.5    95  39650
#> Louisiana.Population        13.2    42.2    12  44930
#> Maine.Population             2.7    54.7   161  30920
#> Maryland.Population          8.5    52.3   101   9891
#> Massachusetts.Population     3.3    58.5   103   7826
#> Michigan.Population         11.1    52.8   125  56817
#> Minnesota.Population         2.3    57.6   160  79289
#> Mississippi.Population      12.5    41.0    50  47296
#> Missouri.Population          9.3    48.8   108  68995
#> Montana.Population           5.0    59.2   155 145587
#> Nebraska.Population          2.9    59.3   139  76483
#> Nevada.Population           11.5    65.2   188 109889
#> New Hampshire.Population     3.3    57.6   174   9027
#> New Jersey.Population        5.2    52.5   115   7521
#> New Mexico.Population        9.7    55.2   120 121412
#> New York.Population         10.9    52.7    82  47831
#> North Carolina.Population   11.1    38.5    80  48798
#> North Dakota.Population      1.4    50.3   186  69273
#> Ohio.Population              7.4    53.2   124  40975
#> Oklahoma.Population          6.4    51.6    82  68782
#> Oregon.Population            4.2    60.0    44  96184
#> Pennsylvania.Population      6.1    50.2   126  44966
#> Rhode Island.Population      2.4    46.4   127   1049
#> South Carolina.Population   11.6    37.8    65  30225
#> South Dakota.Population      1.7    53.3   172  75955
#> Tennessee.Population        11.0    41.8    70  41328
#> Texas.Population            12.2    47.4    35 262134
#> Utah.Population              4.5    67.3   137  82096
#> Vermont.Population           5.5    57.1   168   9267
#> Virginia.Population          9.5    47.8    85  39780
#> Washington.Population        4.3    63.5    32  66570
#> West Virginia.Population     6.7    41.6   100  24070
#> Wisconsin.Population         3.0    54.5   149  54464
#> Wyoming.Population           6.9    62.9   173  97203
reshape(long, direction = "wide", new.row.names = unique(long$state))
#>                         state Population Income Illiteracy Life Exp Murder
#> Alabama               Alabama       3615   3624        2.1    69.05   15.1
#> Alaska                 Alaska        365   6315        1.5    69.31   11.3
#> Arizona               Arizona       2212   4530        1.8    70.55    7.8
#> Arkansas             Arkansas       2110   3378        1.9    70.66   10.1
#> California         California      21198   5114        1.1    71.71   10.3
#> Colorado             Colorado       2541   4884        0.7    72.06    6.8
#> Connecticut       Connecticut       3100   5348        1.1    72.48    3.1
#> Delaware             Delaware        579   4809        0.9    70.06    6.2
#> Florida               Florida       8277   4815        1.3    70.66   10.7
#> Georgia               Georgia       4931   4091        2.0    68.54   13.9
#> Hawaii                 Hawaii        868   4963        1.9    73.60    6.2
#> Idaho                   Idaho        813   4119        0.6    71.87    5.3
#> Illinois             Illinois      11197   5107        0.9    70.14   10.3
#> Indiana               Indiana       5313   4458        0.7    70.88    7.1
#> Iowa                     Iowa       2861   4628        0.5    72.56    2.3
#> Kansas                 Kansas       2280   4669        0.6    72.58    4.5
#> Kentucky             Kentucky       3387   3712        1.6    70.10   10.6
#> Louisiana           Louisiana       3806   3545        2.8    68.76   13.2
#> Maine                   Maine       1058   3694        0.7    70.39    2.7
#> Maryland             Maryland       4122   5299        0.9    70.22    8.5
#> Massachusetts   Massachusetts       5814   4755        1.1    71.83    3.3
#> Michigan             Michigan       9111   4751        0.9    70.63   11.1
#> Minnesota           Minnesota       3921   4675        0.6    72.96    2.3
#> Mississippi       Mississippi       2341   3098        2.4    68.09   12.5
#> Missouri             Missouri       4767   4254        0.8    70.69    9.3
#> Montana               Montana        746   4347        0.6    70.56    5.0
#> Nebraska             Nebraska       1544   4508        0.6    72.60    2.9
#> Nevada                 Nevada        590   5149        0.5    69.03   11.5
#> New Hampshire   New Hampshire        812   4281        0.7    71.23    3.3
#> New Jersey         New Jersey       7333   5237        1.1    70.93    5.2
#> New Mexico         New Mexico       1144   3601        2.2    70.32    9.7
#> New York             New York      18076   4903        1.4    70.55   10.9
#> North Carolina North Carolina       5441   3875        1.8    69.21   11.1
#> North Dakota     North Dakota        637   5087        0.8    72.78    1.4
#> Ohio                     Ohio      10735   4561        0.8    70.82    7.4
#> Oklahoma             Oklahoma       2715   3983        1.1    71.42    6.4
#> Oregon                 Oregon       2284   4660        0.6    72.13    4.2
#> Pennsylvania     Pennsylvania      11860   4449        1.0    70.43    6.1
#> Rhode Island     Rhode Island        931   4558        1.3    71.90    2.4
#> South Carolina South Carolina       2816   3635        2.3    67.96   11.6
#> South Dakota     South Dakota        681   4167        0.5    72.08    1.7
#> Tennessee           Tennessee       4173   3821        1.7    70.11   11.0
#> Texas                   Texas      12237   4188        2.2    70.90   12.2
#> Utah                     Utah       1203   4022        0.6    72.90    4.5
#> Vermont               Vermont        472   3907        0.6    71.64    5.5
#> Virginia             Virginia       4981   4701        1.4    70.08    9.5
#> Washington         Washington       3559   4864        0.6    71.72    4.3
#> West Virginia   West Virginia       1799   3617        1.4    69.48    6.7
#> Wisconsin           Wisconsin       4589   4468        0.7    72.48    3.0
#> Wyoming               Wyoming        376   4566        0.6    70.29    6.9
#>                HS Grad Frost   Area
#> Alabama           41.3    20  50708
#> Alaska            66.7   152 566432
#> Arizona           58.1    15 113417
#> Arkansas          39.9    65  51945
#> California        62.6    20 156361
#> Colorado          63.9   166 103766
#> Connecticut       56.0   139   4862
#> Delaware          54.6   103   1982
#> Florida           52.6    11  54090
#> Georgia           40.6    60  58073
#> Hawaii            61.9     0   6425
#> Idaho             59.5   126  82677
#> Illinois          52.6   127  55748
#> Indiana           52.9   122  36097
#> Iowa              59.0   140  55941
#> Kansas            59.9   114  81787
#> Kentucky          38.5    95  39650
#> Louisiana         42.2    12  44930
#> Maine             54.7   161  30920
#> Maryland          52.3   101   9891
#> Massachusetts     58.5   103   7826
#> Michigan          52.8   125  56817
#> Minnesota         57.6   160  79289
#> Mississippi       41.0    50  47296
#> Missouri          48.8   108  68995
#> Montana           59.2   155 145587
#> Nebraska          59.3   139  76483
#> Nevada            65.2   188 109889
#> New Hampshire     57.6   174   9027
#> New Jersey        52.5   115   7521
#> New Mexico        55.2   120 121412
#> New York          52.7    82  47831
#> North Carolina    38.5    80  48798
#> North Dakota      50.3   186  69273
#> Ohio              53.2   124  40975
#> Oklahoma          51.6    82  68782
#> Oregon            60.0    44  96184
#> Pennsylvania      50.2   126  44966
#> Rhode Island      46.4   127   1049
#> South Carolina    37.8    65  30225
#> South Dakota      53.3   172  75955
#> Tennessee         41.8    70  41328
#> Texas             47.4    35 262134
#> Utah              67.3   137  82096
#> Vermont           57.1   168   9267
#> Virginia          47.8    85  39780
#> Washington        63.5    32  66570
#> West Virginia     41.6   100  24070
#> Wisconsin         54.5   149  54464
#> Wyoming           62.9   173  97203
##=== note : this is a weird example, the column "Population" ends up containing
##=== data which is NOT always population, but which is the value associated 
##=== with the Characteristic column
##=== stats::reshape() gives attributes to its output so we can reshape it from wide to
##=== long without giving parameters, tb doesn't support that, but in this case we can easily do:
long %tb>% .[`{Characteristic}` = Population, .by = "state"]
#>             state Population Income Illiteracy Life Exp Murder HS Grad Frost
#> 1         Alabama       3615   3624        2.1    69.05   15.1    41.3    20
#> 2          Alaska        365   6315        1.5    69.31   11.3    66.7   152
#> 3         Arizona       2212   4530        1.8    70.55    7.8    58.1    15
#> 4        Arkansas       2110   3378        1.9    70.66   10.1    39.9    65
#> 5      California      21198   5114        1.1    71.71   10.3    62.6    20
#> 6        Colorado       2541   4884        0.7    72.06    6.8    63.9   166
#> 7     Connecticut       3100   5348        1.1    72.48    3.1    56.0   139
#> 8        Delaware        579   4809        0.9    70.06    6.2    54.6   103
#> 9         Florida       8277   4815        1.3    70.66   10.7    52.6    11
#> 10        Georgia       4931   4091        2.0    68.54   13.9    40.6    60
#> 11         Hawaii        868   4963        1.9    73.60    6.2    61.9     0
#> 12          Idaho        813   4119        0.6    71.87    5.3    59.5   126
#> 13       Illinois      11197   5107        0.9    70.14   10.3    52.6   127
#> 14        Indiana       5313   4458        0.7    70.88    7.1    52.9   122
#> 15           Iowa       2861   4628        0.5    72.56    2.3    59.0   140
#> 16         Kansas       2280   4669        0.6    72.58    4.5    59.9   114
#> 17       Kentucky       3387   3712        1.6    70.10   10.6    38.5    95
#> 18      Louisiana       3806   3545        2.8    68.76   13.2    42.2    12
#> 19          Maine       1058   3694        0.7    70.39    2.7    54.7   161
#> 20       Maryland       4122   5299        0.9    70.22    8.5    52.3   101
#> 21  Massachusetts       5814   4755        1.1    71.83    3.3    58.5   103
#> 22       Michigan       9111   4751        0.9    70.63   11.1    52.8   125
#> 23      Minnesota       3921   4675        0.6    72.96    2.3    57.6   160
#> 24    Mississippi       2341   3098        2.4    68.09   12.5    41.0    50
#> 25       Missouri       4767   4254        0.8    70.69    9.3    48.8   108
#> 26        Montana        746   4347        0.6    70.56    5.0    59.2   155
#> 27       Nebraska       1544   4508        0.6    72.60    2.9    59.3   139
#> 28         Nevada        590   5149        0.5    69.03   11.5    65.2   188
#> 29  New Hampshire        812   4281        0.7    71.23    3.3    57.6   174
#> 30     New Jersey       7333   5237        1.1    70.93    5.2    52.5   115
#> 31     New Mexico       1144   3601        2.2    70.32    9.7    55.2   120
#> 32       New York      18076   4903        1.4    70.55   10.9    52.7    82
#> 33 North Carolina       5441   3875        1.8    69.21   11.1    38.5    80
#> 34   North Dakota        637   5087        0.8    72.78    1.4    50.3   186
#> 35           Ohio      10735   4561        0.8    70.82    7.4    53.2   124
#> 36       Oklahoma       2715   3983        1.1    71.42    6.4    51.6    82
#> 37         Oregon       2284   4660        0.6    72.13    4.2    60.0    44
#> 38   Pennsylvania      11860   4449        1.0    70.43    6.1    50.2   126
#> 39   Rhode Island        931   4558        1.3    71.90    2.4    46.4   127
#> 40 South Carolina       2816   3635        2.3    67.96   11.6    37.8    65
#> 41   South Dakota        681   4167        0.5    72.08    1.7    53.3   172
#> 42      Tennessee       4173   3821        1.7    70.11   11.0    41.8    70
#> 43          Texas      12237   4188        2.2    70.90   12.2    47.4    35
#> 44           Utah       1203   4022        0.6    72.90    4.5    67.3   137
#> 45        Vermont        472   3907        0.6    71.64    5.5    57.1   168
#> 46       Virginia       4981   4701        1.4    70.08    9.5    47.8    85
#> 47     Washington       3559   4864        0.6    71.72    4.3    63.5    32
#> 48  West Virginia       1799   3617        1.4    69.48    6.7    41.6   100
#> 49      Wisconsin       4589   4468        0.7    72.48    3.0    54.5   149
#> 50        Wyoming        376   4566        0.6    70.29    6.9    62.9   173
#>      Area
#> 1   50708
#> 2  566432
#> 3  113417
#> 4   51945
#> 5  156361
#> 6  103766
#> 7    4862
#> 8    1982
#> 9   54090
#> 10  58073
#> 11   6425
#> 12  82677
#> 13  55748
#> 14  36097
#> 15  55941
#> 16  81787
#> 17  39650
#> 18  44930
#> 19  30920
#> 20   9891
#> 21   7826
#> 22  56817
#> 23  79289
#> 24  47296
#> 25  68995
#> 26 145587
#> 27  76483
#> 28 109889
#> 29   9027
#> 30   7521
#> 31 121412
#> 32  47831
#> 33  48798
#> 34  69273
#> 35  40975
#> 36  68782
#> 37  96184
#> 38  44966
#> 39   1049
#> 40  30225
#> 41  75955
#> 42  41328
#> 43 262134
#> 44  82096
#> 45   9267
#> 46  39780
#> 47  66570
#> 48  24070
#> 49  54464
#> 50  97203

## multiple id variables
df3 <- data.frame(school = rep(1:3, each = 4), class = rep(9:10, 6),
                  time = rep(c(1,1,2,2), 3), score = rnorm(12))
wide2 <- reshape(df3, idvar = c("school","class"), direction = "wide")
wide2
#>    school class    score.1     score.2
#> 1       1     9  0.1081122  0.02204206
#> 2       1    10 -0.1525912 -0.70710255
#> 5       2     9  1.6319293  0.52060969
#> 6       2    10  2.4800495  1.01616640
#> 9       3     9  0.7597366  0.40405057
#> 10      3    10 -0.3360911 -0.09803899
df3 %tb>% .[`score.{time}` = score, .by = s(school, class)]
#>   school class    score.1     score.2
#> 1      1     9  0.1081122  0.02204206
#> 2      1    10  1.6319293  0.52060969
#> 3      2     9  0.7597366  0.40405057
#> 4      2    10 -0.1525912 -0.70710255
#> 5      3     9  2.4800495  1.01616640
#> 6      3    10 -0.3360911 -0.09803899

## transform back
reshape(wide2)
#>        school class time     score.1
#> 1.9.1       1     9    1  0.10811224
#> 1.10.1      1    10    1 -0.15259123
#> 2.9.1       2     9    1  1.63192927
#> 2.10.1      2    10    1  2.48004955
#> 3.9.1       3     9    1  0.75973656
#> 3.10.1      3    10    1 -0.33609110
#> 1.9.2       1     9    2  0.02204206
#> 1.10.2      1    10    2 -0.70710255
#> 2.9.2       2     9    2  0.52060969
#> 2.10.2      2    10    2  1.01616640
#> 3.9.2       3     9    2  0.40405057
#> 3.10.2      3    10    2 -0.09803899
#=== as said above we don't support this

#################### reshape with direction = "long"

wide
#>    Subject conc.0.25 conc.0.5 conc.0.75 conc.1 conc.1.25 conc.2 conc.3 conc.4
#> 1        1      1.50     0.94      0.78   0.48      0.37   0.19   0.12   0.11
#> 12       2      2.03     1.63      0.71   0.70      0.64   0.36   0.32   0.20
#> 23       3      2.72     1.49      1.16   0.80      0.80   0.39   0.22   0.12
#> 34       4      1.85     1.39      1.02   0.89      0.59   0.40   0.16   0.11
#> 45       5      2.05     1.04      0.81   0.39      0.30   0.23   0.13   0.11
#> 56       6      2.31     1.44      1.03   0.84      0.64   0.42   0.24   0.17
#>    conc.5 conc.6 conc.8
#> 1    0.08   0.07   0.05
#> 12   0.25   0.12   0.08
#> 23   0.11   0.08   0.08
#> 34   0.10   0.07   0.07
#> 45   0.08   0.10   0.06
#> 56   0.13   0.10   0.09
reshape(wide, direction = "long")
#>        Subject time conc
#> 1.0.25       1 0.25 1.50
#> 2.0.25       2 0.25 2.03
#> 3.0.25       3 0.25 2.72
#> 4.0.25       4 0.25 1.85
#> 5.0.25       5 0.25 2.05
#> 6.0.25       6 0.25 2.31
#> 1.0.5        1 0.50 0.94
#> 2.0.5        2 0.50 1.63
#> 3.0.5        3 0.50 1.49
#> 4.0.5        4 0.50 1.39
#> 5.0.5        5 0.50 1.04
#> 6.0.5        6 0.50 1.44
#> 1.0.75       1 0.75 0.78
#> 2.0.75       2 0.75 0.71
#> 3.0.75       3 0.75 1.16
#> 4.0.75       4 0.75 1.02
#> 5.0.75       5 0.75 0.81
#> 6.0.75       6 0.75 1.03
#> 1.1          1 1.00 0.48
#> 2.1          2 1.00 0.70
#> 3.1          3 1.00 0.80
#> 4.1          4 1.00 0.89
#> 5.1          5 1.00 0.39
#> 6.1          6 1.00 0.84
#> 1.1.25       1 1.25 0.37
#> 2.1.25       2 1.25 0.64
#> 3.1.25       3 1.25 0.80
#> 4.1.25       4 1.25 0.59
#> 5.1.25       5 1.25 0.30
#> 6.1.25       6 1.25 0.64
#> 1.2          1 2.00 0.19
#> 2.2          2 2.00 0.36
#> 3.2          3 2.00 0.39
#> 4.2          4 2.00 0.40
#> 5.2          5 2.00 0.23
#> 6.2          6 2.00 0.42
#> 1.3          1 3.00 0.12
#> 2.3          2 3.00 0.32
#> 3.3          3 3.00 0.22
#> 4.3          4 3.00 0.16
#> 5.3          5 3.00 0.13
#> 6.3          6 3.00 0.24
#> 1.4          1 4.00 0.11
#> 2.4          2 4.00 0.20
#> 3.4          3 4.00 0.12
#> 4.4          4 4.00 0.11
#> 5.4          5 4.00 0.11
#> 6.4          6 4.00 0.17
#> 1.5          1 5.00 0.08
#> 2.5          2 5.00 0.25
#> 3.5          3 5.00 0.11
#> 4.5          4 5.00 0.10
#> 5.5          5 5.00 0.08
#> 6.5          6 5.00 0.13
#> 1.6          1 6.00 0.07
#> 2.6          2 6.00 0.12
#> 3.6          3 6.00 0.08
#> 4.6          4 6.00 0.07
#> 5.6          5 6.00 0.10
#> 6.6          6 6.00 0.10
#> 1.8          1 8.00 0.05
#> 2.8          2 8.00 0.08
#> 3.8          3 8.00 0.08
#> 4.8          4 8.00 0.07
#> 5.8          5 8.00 0.06
#> 6.8          6 8.00 0.09
reshape(wide, idvar = "Subject", varying = list(2:12),
        v.names = "conc", direction = "long")
#>      Subject time conc
#> 1.1        1    1 1.50
#> 2.1        2    1 2.03
#> 3.1        3    1 2.72
#> 4.1        4    1 1.85
#> 5.1        5    1 2.05
#> 6.1        6    1 2.31
#> 1.2        1    2 0.94
#> 2.2        2    2 1.63
#> 3.2        3    2 1.49
#> 4.2        4    2 1.39
#> 5.2        5    2 1.04
#> 6.2        6    2 1.44
#> 1.3        1    3 0.78
#> 2.3        2    3 0.71
#> 3.3        3    3 1.16
#> 4.3        4    3 1.02
#> 5.3        5    3 0.81
#> 6.3        6    3 1.03
#> 1.4        1    4 0.48
#> 2.4        2    4 0.70
#> 3.4        3    4 0.80
#> 4.4        4    4 0.89
#> 5.4        5    4 0.39
#> 6.4        6    4 0.84
#> 1.5        1    5 0.37
#> 2.5        2    5 0.64
#> 3.5        3    5 0.80
#> 4.5        4    5 0.59
#> 5.5        5    5 0.30
#> 6.5        6    5 0.64
#> 1.6        1    6 0.19
#> 2.6        2    6 0.36
#> 3.6        3    6 0.39
#> 4.6        4    6 0.40
#> 5.6        5    6 0.23
#> 6.6        6    6 0.42
#> 1.7        1    7 0.12
#> 2.7        2    7 0.32
#> 3.7        3    7 0.22
#> 4.7        4    7 0.16
#> 5.7        5    7 0.13
#> 6.7        6    7 0.24
#> 1.8        1    8 0.11
#> 2.8        2    8 0.20
#> 3.8        3    8 0.12
#> 4.8        4    8 0.11
#> 5.8        5    8 0.11
#> 6.8        6    8 0.17
#> 1.9        1    9 0.08
#> 2.9        2    9 0.25
#> 3.9        3    9 0.11
#> 4.9        4    9 0.10
#> 5.9        5    9 0.08
#> 6.9        6    9 0.13
#> 1.10       1   10 0.07
#> 2.10       2   10 0.12
#> 3.10       3   10 0.08
#> 4.10       4   10 0.07
#> 5.10       5   10 0.10
#> 6.10       6   10 0.10
#> 1.11       1   11 0.05
#> 2.11       2   11 0.08
#> 3.11       3   11 0.08
#> 4.11       4   11 0.07
#> 5.11       5   11 0.06
#> 6.11       6   11 0.09

## Alternative regular expressions for guessing names
df3 <- data.frame(id = 1:4, age = c(40,50,60,50), dose1 = c(1,2,1,2),
                  dose2 = c(2,1,2,1), dose4 = c(3,3,3,3))
reshape(df3, direction = "long", varying = 3:5, sep = "")
#>     id age time dose
#> 1.1  1  40    1    1
#> 2.1  2  50    1    2
#> 3.1  3  60    1    1
#> 4.1  4  50    1    2
#> 1.2  1  40    2    2
#> 2.2  2  50    2    1
#> 3.2  3  60    2    2
#> 4.2  4  50    2    1
#> 1.4  1  40    4    3
#> 2.4  2  50    4    3
#> 3.4  3  60    4    3
#> 4.4  4  50    4    3

Created on 2020-01-27 by the reprex package (v0.3.0)

moodymudskipper commented 4 years ago

gather examples :

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(tidyr)
library(tb)

### to wide

stocks <- data.frame(
  time = as.Date('2009-01-01') + 0:9,
  X = rnorm(10, 0, 1),
  Y = rnorm(10, 0, 2),
  Z = rnorm(10, 0, 4)
)
stocksm <- stocks %>% gather(stock, price, -time)
stocksm %>% spread(stock, price)
#>          time          X          Y           Z
#> 1  2009-01-01  0.5433287  2.0440656 -3.00698108
#> 2  2009-01-02 -1.2206002 -1.4562860  3.77449811
#> 3  2009-01-03 -0.4773918 -1.5488332  0.08087886
#> 4  2009-01-04  1.0317774 -2.5863277 -5.10991179
#> 5  2009-01-05 -0.2312186 -2.4047084 -7.68613725
#> 6  2009-01-06  0.2153001  0.5612536  2.92042582
#> 7  2009-01-07  0.7793458 -2.5045450  2.34881428
#> 8  2009-01-08 -0.1289938  0.5152197  2.51203859
#> 9  2009-01-09  0.1979628 -2.0947885 13.05672996
#> 10 2009-01-10 -1.9806814  0.2030949 -3.06399989
stocksm %>% 
  # because of tb bug!
  mutate(time = as.character(time)) %tb>% 
  .[`{stock}` = price, .by = "time"]
#>          time          X          Y           Z
#> 1  2009-01-01  0.5433287  2.0440656 -3.00698108
#> 2  2009-01-02 -1.2206002 -1.4562860  3.77449811
#> 3  2009-01-03 -0.4773918 -1.5488332  0.08087886
#> 4  2009-01-04  1.0317774 -2.5863277 -5.10991179
#> 5  2009-01-05 -0.2312186 -2.4047084 -7.68613725
#> 6  2009-01-06  0.2153001  0.5612536  2.92042582
#> 7  2009-01-07  0.7793458 -2.5045450  2.34881428
#> 8  2009-01-08 -0.1289938  0.5152197  2.51203859
#> 9  2009-01-09  0.1979628 -2.0947885 13.05672996
#> 10 2009-01-10 -1.9806814  0.2030949 -3.06399989
stocksm %>% spread(time, price)
#>   stock 2009-01-01 2009-01-02  2009-01-03 2009-01-04 2009-01-05 2009-01-06
#> 1     X  0.5433287  -1.220600 -0.47739180   1.031777 -0.2312186  0.2153001
#> 2     Y  2.0440656  -1.456286 -1.54883316  -2.586328 -2.4047084  0.5612536
#> 3     Z -3.0069811   3.774498  0.08087886  -5.109912 -7.6861372  2.9204258
#>   2009-01-07 2009-01-08 2009-01-09 2009-01-10
#> 1  0.7793458 -0.1289938  0.1979628 -1.9806814
#> 2 -2.5045450  0.5152197 -2.0947885  0.2030949
#> 3  2.3488143  2.5120386 13.0567300 -3.0639999

# Spread and gather are complements
df <- data.frame(x = c("a", "b"), y = c(3, 4), z = c(5, 6))
res <- df %>% spread(x, y) 
res
#>   z  a  b
#> 1 5  3 NA
#> 2 6 NA  4
df %tb>% .[`{x}` = y, .by = "z"]
#>   z  a  b
#> 1 5  3 NA
#> 2 6 NA  4

# Use 'convert = TRUE' to produce variables of mixed type
df <- data.frame(row = rep(c(1, 51), each = 3),
                 var = c("Sepal.Length", "Species", "Species_num"),
                 value = c(5.1, "setosa", 1, 7.0, "versicolor", 2))
df %>% spread(var, value) %>% str
#> 'data.frame':    2 obs. of  4 variables:
#>  $ row         : num  1 51
#>  $ Sepal.Length: Factor w/ 6 levels "1","2","5.1",..: 3 4
#>  $ Species     : Factor w/ 6 levels "1","2","5.1",..: 5 6
#>  $ Species_num : Factor w/ 6 levels "1","2","5.1",..: 1 2
df %>% spread(var, value, convert = TRUE) %>% str
#> 'data.frame':    2 obs. of  4 variables:
#>  $ row         : num  1 51
#>  $ Sepal.Length: num  5.1 7
#>  $ Species     : chr  "setosa" "versicolor"
#>  $ Species_num : int  1 2
df %tb>% .[`{var}` = value, .by = "row"] %>% str
#> 'data.frame':    2 obs. of  4 variables:
#>  $ row         : num  1 51
#>  $ Sepal.Length: Factor w/ 6 levels "1","2","5.1",..: 3 4
#>  $ Species     : Factor w/ 6 levels "1","2","5.1",..: 5 6
#>  $ Species_num : Factor w/ 6 levels "1","2","5.1",..: 1 2
#=== we don't need a convert option because we can modify right in the call
df %tb>% .[`{var}` = type.convert(value, as.is = TRUE), .by = "row"] %>% str
#> 'data.frame':    2 obs. of  4 variables:
#>  $ row         : num  1 51
#>  $ Sepal.Length: num  5.1 7
#>  $ Species     : chr  "setosa" "versicolor"
#>  $ Species_num : int  1 2
#=== maybe include convert function in pkg as it's convenient, and then once we have auto .by:
# convert <- function(x) type.convert(x, as.is = TRUE)
# df %tb>% .[`{var}` = convert(value)] %>% str

## to long

res %>% gather("x", "y", a:b, na.rm = TRUE)
#>   z x y
#> 1 5 a 3
#> 4 6 b 4

Created on 2020-01-27 by the reprex package (v0.3.0)

moodymudskipper commented 4 years ago

Maybe .index should be a parameter, and by convention it would be applied right after .i and .j ? (before ...), or maybe better, forbid the use of .i and .j when using .index :

#== This would index with names "key" and "value", and fail if these exist already
mini_iris %tb>%
  .[.index = s(-Species)]
#== This would rename, as a separate operation
mini_iris %tb>%
  .[.index = s(-Species), {key} = "flower_att", {value} = "measurement"]

Just as in gather in this proposal we don't mention explicitly the renaming columns, which will be duplicated. But I don't recall it being a problem with gather(). If needed we could use the along convention and do :

mini_iris %tb>%
  .[.index = s(foo) ~ Species, {key} = "flower_att", {value} = "measurement"]

or to gather all columns automatically :

mini_iris %tb>%
  .[.index = ~ Species, {key} = "flower_att", {value} = "measurement"]

But it seems that a previous step of selection if necessary + using s(-Species) is enough

moodymudskipper commented 4 years ago

Most reshape2::dcast examples :

library(reshape2)
library(tb)
#Air quality example
names(airquality) <- tolower(names(airquality))
aqm <- melt(airquality, id=c("month", "day"), na.rm=TRUE)

dcast(aqm, month ~ variable, mean, margins = c("month", "variable"))
#>   month    ozone  solar.r      wind     temp    (all)
#> 1     5 23.61538 181.2963 11.622581 65.54839 68.70696
#> 2     6 29.44444 190.1667 10.266667 79.10000 87.38384
#> 3     7 59.11538 216.4839  8.941935 83.90323 93.49748
#> 4     8 59.96154 171.8571  8.793548 83.96774 79.71207
#> 5     9 31.44828 167.4333 10.180000 76.90000 71.82689
#> 6 (all) 42.12931 185.9315  9.957516 77.88235 80.05722
aqm %tb>%
  .[`{variable}` = mean(value), .by = "month"]
#>   month    ozone  solar.r      wind     temp
#> 1     5 23.61538 181.2963 11.622581 65.54839
#> 2     6 29.44444 190.1667 10.266667 79.10000
#> 3     7 59.11538 216.4839  8.941935 83.90323
#> 4     8 59.96154 171.8571  8.793548 83.96774
#> 5     9 31.44828 167.4333 10.180000 76.90000
#== tb doesn't feature an option for margins as reshape2 does
#== We could easily add the (all) column if needed though
aqm %tb>%
  .[`{variable}` = mean(value), `(all)` = mean(value), .by = "month"]
#>   month    ozone  solar.r      wind     temp    (all)
#> 1     5 23.61538 181.2963 11.622581 65.54839 68.70696
#> 2     6 29.44444 190.1667 10.266667 79.10000 87.38384
#> 3     7 59.11538 216.4839  8.941935 83.90323 93.49748
#> 4     8 59.96154 171.8571  8.793548 83.96774 79.71207
#> 5     9 31.44828 167.4333 10.180000 76.90000 71.82689
#== to add the row we'll need to implement https://github.com/moodymudskipper/tb/issues/23
#== now we can do
aqm %>%
  rbind(., . %tb>% .[month = "(all)"]) %tb>%
  .[`{variable}` = mean(value), `(all)` = mean(value), .by = "month"]
#> Error in aqm %>% rbind(., . %tb>% .[month = "(all)"]): could not find function "%>%"
#== and we'll do
# aqm %tb>%
#   .[+.x[month="(all)"], 
#     `{variable}` = mean(value), 
#     `(all)` = mean(value), 
#     .by = "month"]

library(plyr) # needed to access . function
dcast(aqm, variable ~ month, mean, subset = .(variable == "ozone"))
#>   variable        5        6        7        8        9
#> 1    ozone 23.61538 29.44444 59.11538 59.96154 31.44828
aqm %tb>% .[variable == "ozone", `{month}` = mean(value), .by="variable"]
#>   variable        5        6        7        8        9
#> 1    ozone 23.61538 29.44444 59.11538 59.96154 31.44828
dcast(aqm, variable ~ month, mean, subset = .(month == 5))
#>   variable         5
#> 1    ozone  23.61538
#> 2  solar.r 181.29630
#> 3     wind  11.62258
#> 4     temp  65.54839
aqm %tb>% .[month == 5, `{month}` = mean(value), .by="variable"]
#>   variable         5
#> 1    ozone  23.61538
#> 2  solar.r 181.29630
#> 3     wind  11.62258
#> 4     temp  65.54839

#Chick weight example
names(ChickWeight) <- tolower(names(ChickWeight))
chick_m <- melt(ChickWeight, id=2:4, na.rm=TRUE)

dcast(chick_m, time ~ variable, mean) # average effect of time
#>    time    weight
#> 1     0  41.06000
#> 2     2  49.22000
#> 3     4  59.95918
#> 4     6  74.30612
#> 5     8  91.24490
#> 6    10 107.83673
#> 7    12 129.24490
#> 8    14 143.81250
#> 9    16 168.08511
#> 10   18 190.19149
#> 11   20 209.71739
#> 12   21 218.68889
chick_m %tb>% .[`{variable}` = mean(value), .by = "time"]
#>    time    weight
#> 1     0  41.06000
#> 2     2  49.22000
#> 3     4  59.95918
#> 4     6  74.30612
#> 5     8  91.24490
#> 6    10 107.83673
#> 7    12 129.24490
#> 8    14 143.81250
#> 9    16 168.08511
#> 10   18 190.19149
#> 11   20 209.71739
#> 12   21 218.68889
dcast(chick_m, diet ~ variable, mean) # average effect of diet
#>   diet   weight
#> 1    1 102.6455
#> 2    2 122.6167
#> 3    3 142.9500
#> 4    4 135.2627
chick_m %tb>% .[`{variable}` = mean(value), .by = "diet"]
#>   diet   weight
#> 1    1 102.6455
#> 2    2 122.6167
#> 3    3 142.9500
#> 4    4 135.2627
dcast(chick_m, diet ~ time, mean) # average effect of diet & time
#>   diet    0     2        4        6         8        10       12       14
#> 1    1 41.4 47.25 56.47368 66.78947  79.68421  93.05263 108.5263 123.3889
#> 2    2 40.7 49.40 59.80000 75.40000  91.70000 108.50000 131.3000 141.9000
#> 3    3 40.8 50.40 62.20000 77.90000  98.40000 117.10000 144.4000 164.5000
#> 4    4 41.0 51.80 64.50000 83.90000 105.60000 126.00000 151.4000 161.8000
#>         16       18       20       21
#> 1 144.6471 158.9412 170.4118 177.7500
#> 2 164.7000 187.7000 205.6000 214.7000
#> 3 197.4000 233.1000 258.9000 270.3000
#> 4 182.0000 202.9000 233.8889 238.5556
chick_m %tb>% .[`{time}` = mean(value), .by = "diet"]
#>   diet    0     2        4        6         8        10       12       14
#> 1    1 41.4 47.25 56.47368 66.78947  79.68421  93.05263 108.5263 123.3889
#> 2    2 40.7 49.40 59.80000 75.40000  91.70000 108.50000 131.3000 141.9000
#> 3    3 40.8 50.40 62.20000 77.90000  98.40000 117.10000 144.4000 164.5000
#> 4    4 41.0 51.80 64.50000 83.90000 105.60000 126.00000 151.4000 161.8000
#>         16       18       20       21
#> 1 144.6471 158.9412 170.4118 177.7500
#> 2 164.7000 187.7000 205.6000 214.7000
#> 3 197.4000 233.1000 258.9000 270.3000
#> 4 182.0000 202.9000 233.8889 238.5556

# How many chicks at each time? - checking for balance
dcast(chick_m, time ~ diet, length)
#>    time  1  2  3  4
#> 1     0 20 10 10 10
#> 2     2 20 10 10 10
#> 3     4 19 10 10 10
#> 4     6 19 10 10 10
#> 5     8 19 10 10 10
#> 6    10 19 10 10 10
#> 7    12 19 10 10 10
#> 8    14 18 10 10 10
#> 9    16 17 10 10 10
#> 10   18 17 10 10 10
#> 11   20 17 10 10  9
#> 12   21 16 10 10  9
chick_m %tb>% .[`{diet}` = length(value), .by = "time"]
#>    time  1  2  3  4
#> 1     0 20 10 10 10
#> 2     2 20 10 10 10
#> 3     4 19 10 10 10
#> 4     6 19 10 10 10
#> 5     8 19 10 10 10
#> 6    10 19 10 10 10
#> 7    12 19 10 10 10
#> 8    14 18 10 10 10
#> 9    16 17 10 10 10
#> 10   18 17 10 10 10
#> 11   20 17 10 10  9
#> 12   21 16 10 10  9
# or
chick_m %tb>% .[`{diet}` = nrow(.subset), .by = "time"]
#>    time  1  2  3  4
#> 1     0 20 10 10 10
#> 2     2 20 10 10 10
#> 3     4 19 10 10 10
#> 4     6 19 10 10 10
#> 5     8 19 10 10 10
#> 6    10 19 10 10 10
#> 7    12 19 10 10 10
#> 8    14 18 10 10 10
#> 9    16 17 10 10 10
#> 10   18 17 10 10 10
#> 11   20 17 10 10  9
#> 12   21 16 10 10  9
#chick_m %tb>% .[`{diet}` = .N, .by = "time"]
dcast(chick_m, chick ~ time, mean)
#>    chick  0  2   4   6   8  10  12  14  16  18  20  21
#> 1     18 39 35 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
#> 2     16 41 45  49  51  57  51  54 NaN NaN NaN NaN NaN
#> 3     15 41 49  56  64  68  68  67  68 NaN NaN NaN NaN
#> 4     13 41 48  53  60  65  67  71  70  71  81  91  96
#> 5      9 42 51  59  68  85  96  90  92  93 100 100  98
#> 6     20 41 47  54  58  65  73  77  89  98 107 115 117
#> 7     10 41 44  52  63  74  81  89  96 101 112 120 124
#> 8      8 42 50  61  71  84  93 110 116 126 134 125 NaN
#> 9     17 42 51  61  72  83  89  98 103 113 123 133 142
#> 10    19 43 48  55  62  65  71  82  88 106 120 144 157
#> 11     4 42 49  56  67  74  87 102 108 136 154 160 157
#> 12     6 41 49  59  74  97 124 141 148 155 160 160 157
#> 13    11 43 51  63  84 112 139 168 177 182 184 181 175
#> 14     3 43 39  55  67  84  99 115 138 163 187 198 202
#> 15     1 42 51  59  64  76  93 106 125 149 171 199 205
#> 16    12 41 49  56  62  72  88 119 135 162 185 195 205
#> 17     2 40 49  58  72  84 103 122 138 162 187 209 215
#> 18     5 41 42  48  60  79 106 141 164 197 199 220 223
#> 19    14 41 49  62  79 101 128 164 192 227 248 259 266
#> 20     7 41 49  57  71  89 112 146 174 218 250 288 305
#> 21    24 42 52  58  74  66  68  70  71  72  72  76  74
#> 22    30 42 48  59  72  85  98 115 122 143 151 157 150
#> 23    22 41 55  64  77  90  95 108 111 131 148 164 167
#> 24    23 43 52  61  73  90 103 127 135 145 163 170 175
#> 25    27 39 46  58  73  87 100 115 123 144 163 185 192
#> 26    28 39 46  58  73  92 114 145 156 184 207 212 233
#> 27    26 42 48  57  74  93 114 136 147 169 205 236 251
#> 28    25 40 49  62  78 102 124 146 164 197 231 259 265
#> 29    29 39 48  59  74  87 106 134 150 187 230 279 309
#> 30    21 40 50  62  86 125 163 217 240 275 307 318 331
#> 31    33 39 50  63  77  96 111 137 144 151 146 156 147
#> 32    37 41 48  56  68  80  83 103 112 135 157 169 178
#> 33    36 39 48  61  76  98 116 145 166 198 227 225 220
#> 34    31 42 53  62  73  85 102 123 138 170 204 235 256
#> 35    39 42 50  61  78  89 109 130 146 170 214 250 272
#> 36    38 41 49  61  74  98 109 128 154 192 232 280 290
#> 37    32 41 49  65  82 107 129 159 179 221 263 291 305
#> 38    40 41 55  66  79 101 120 154 182 215 262 295 321
#> 39    34 41 49  63  85 107 134 164 186 235 294 327 341
#> 40    35 41 53  64  87 123 158 201 238 287 332 361 373
#> 41    44 42 51  65  86 103 118 127 138 145 146 NaN NaN
#> 42    45 41 50  61  78  98 117 135 141 147 174 197 196
#> 43    43 42 55  69  96 131 157 184 188 197 198 199 200
#> 44    41 42 51  66  85 103 124 155 153 175 184 199 204
#> 45    47 41 53  66  79 100 123 148 157 168 185 210 205
#> 46    49 40 53  64  85 108 128 152 166 184 203 233 237
#> 47    46 40 52  62  82 101 120 144 156 173 210 231 238
#> 48    50 41 54  67  84 105 122 155 175 205 234 264 264
#> 49    42 42 49  63  84 103 126 160 174 204 234 269 281
#> 50    48 39 50  62  80 104 125 154 170 222 261 303 322
chick_m %tb>% .[`{time}` = mean(value), .by = "chick"]
#>    chick  0  2  4  6   8  10  12  14  16  18  20  21
#> 1      1 42 51 59 64  76  93 106 125 149 171 199 205
#> 2      2 40 49 58 72  84 103 122 138 162 187 209 215
#> 3      3 43 39 55 67  84  99 115 138 163 187 198 202
#> 4      4 42 49 56 67  74  87 102 108 136 154 160 157
#> 5      5 41 42 48 60  79 106 141 164 197 199 220 223
#> 6      6 41 49 59 74  97 124 141 148 155 160 160 157
#> 7      7 41 49 57 71  89 112 146 174 218 250 288 305
#> 8      8 42 50 61 71  84  93 110 116 126 134 125  NA
#> 9      9 42 51 59 68  85  96  90  92  93 100 100  98
#> 10    10 41 44 52 63  74  81  89  96 101 112 120 124
#> 11    11 43 51 63 84 112 139 168 177 182 184 181 175
#> 12    12 41 49 56 62  72  88 119 135 162 185 195 205
#> 13    13 41 48 53 60  65  67  71  70  71  81  91  96
#> 14    14 41 49 62 79 101 128 164 192 227 248 259 266
#> 15    15 41 49 56 64  68  68  67  68  NA  NA  NA  NA
#> 16    16 41 45 49 51  57  51  54  NA  NA  NA  NA  NA
#> 17    17 42 51 61 72  83  89  98 103 113 123 133 142
#> 18    18 39 35 NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 19    19 43 48 55 62  65  71  82  88 106 120 144 157
#> 20    20 41 47 54 58  65  73  77  89  98 107 115 117
#> 21    21 40 50 62 86 125 163 217 240 275 307 318 331
#> 22    22 41 55 64 77  90  95 108 111 131 148 164 167
#> 23    23 43 52 61 73  90 103 127 135 145 163 170 175
#> 24    24 42 52 58 74  66  68  70  71  72  72  76  74
#> 25    25 40 49 62 78 102 124 146 164 197 231 259 265
#> 26    26 42 48 57 74  93 114 136 147 169 205 236 251
#> 27    27 39 46 58 73  87 100 115 123 144 163 185 192
#> 28    28 39 46 58 73  92 114 145 156 184 207 212 233
#> 29    29 39 48 59 74  87 106 134 150 187 230 279 309
#> 30    30 42 48 59 72  85  98 115 122 143 151 157 150
#> 31    31 42 53 62 73  85 102 123 138 170 204 235 256
#> 32    32 41 49 65 82 107 129 159 179 221 263 291 305
#> 33    33 39 50 63 77  96 111 137 144 151 146 156 147
#> 34    34 41 49 63 85 107 134 164 186 235 294 327 341
#> 35    35 41 53 64 87 123 158 201 238 287 332 361 373
#> 36    36 39 48 61 76  98 116 145 166 198 227 225 220
#> 37    37 41 48 56 68  80  83 103 112 135 157 169 178
#> 38    38 41 49 61 74  98 109 128 154 192 232 280 290
#> 39    39 42 50 61 78  89 109 130 146 170 214 250 272
#> 40    40 41 55 66 79 101 120 154 182 215 262 295 321
#> 41    41 42 51 66 85 103 124 155 153 175 184 199 204
#> 42    42 42 49 63 84 103 126 160 174 204 234 269 281
#> 43    43 42 55 69 96 131 157 184 188 197 198 199 200
#> 44    44 42 51 65 86 103 118 127 138 145 146  NA  NA
#> 45    45 41 50 61 78  98 117 135 141 147 174 197 196
#> 46    46 40 52 62 82 101 120 144 156 173 210 231 238
#> 47    47 41 53 66 79 100 123 148 157 168 185 210 205
#> 48    48 39 50 62 80 104 125 154 170 222 261 303 322
#> 49    49 40 53 64 85 108 128 152 166 184 203 233 237
#> 50    50 41 54 67 84 105 122 155 175 205 234 264 264
dcast(chick_m, chick ~ time, mean, subset = .(time < 10 & chick < 20))
#>   chick  0  2   4   6   8
#> 1    18 39 35 NaN NaN NaN
#> 2    16 41 45  49  51  57
#> 3    15 41 49  56  64  68
#> 4    13 41 48  53  60  65
#> 5     9 42 51  59  68  85
chick_m %tb>% .[time < 10 & chick < 20, `{time}` = mean(value), .by = "chick"]
#>   chick  0  2  4  6  8
#> 1     9 42 51 59 68 85
#> 2    13 41 48 53 60 65
#> 3    15 41 49 56 64 68
#> 4    16 41 45 49 51 57
#> 5    18 39 35 NA NA NA

dcast(chick_m, diet + chick ~ time)
#>    diet chick  0  2  4  6   8  10  12  14  16  18  20  21
#> 1     1    18 39 35 NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 2     1    16 41 45 49 51  57  51  54  NA  NA  NA  NA  NA
#> 3     1    15 41 49 56 64  68  68  67  68  NA  NA  NA  NA
#> 4     1    13 41 48 53 60  65  67  71  70  71  81  91  96
#> 5     1     9 42 51 59 68  85  96  90  92  93 100 100  98
#> 6     1    20 41 47 54 58  65  73  77  89  98 107 115 117
#> 7     1    10 41 44 52 63  74  81  89  96 101 112 120 124
#> 8     1     8 42 50 61 71  84  93 110 116 126 134 125  NA
#> 9     1    17 42 51 61 72  83  89  98 103 113 123 133 142
#> 10    1    19 43 48 55 62  65  71  82  88 106 120 144 157
#> 11    1     4 42 49 56 67  74  87 102 108 136 154 160 157
#> 12    1     6 41 49 59 74  97 124 141 148 155 160 160 157
#> 13    1    11 43 51 63 84 112 139 168 177 182 184 181 175
#> 14    1     3 43 39 55 67  84  99 115 138 163 187 198 202
#> 15    1     1 42 51 59 64  76  93 106 125 149 171 199 205
#> 16    1    12 41 49 56 62  72  88 119 135 162 185 195 205
#> 17    1     2 40 49 58 72  84 103 122 138 162 187 209 215
#> 18    1     5 41 42 48 60  79 106 141 164 197 199 220 223
#> 19    1    14 41 49 62 79 101 128 164 192 227 248 259 266
#> 20    1     7 41 49 57 71  89 112 146 174 218 250 288 305
#> 21    2    24 42 52 58 74  66  68  70  71  72  72  76  74
#> 22    2    30 42 48 59 72  85  98 115 122 143 151 157 150
#> 23    2    22 41 55 64 77  90  95 108 111 131 148 164 167
#> 24    2    23 43 52 61 73  90 103 127 135 145 163 170 175
#> 25    2    27 39 46 58 73  87 100 115 123 144 163 185 192
#> 26    2    28 39 46 58 73  92 114 145 156 184 207 212 233
#> 27    2    26 42 48 57 74  93 114 136 147 169 205 236 251
#> 28    2    25 40 49 62 78 102 124 146 164 197 231 259 265
#> 29    2    29 39 48 59 74  87 106 134 150 187 230 279 309
#> 30    2    21 40 50 62 86 125 163 217 240 275 307 318 331
#> 31    3    33 39 50 63 77  96 111 137 144 151 146 156 147
#> 32    3    37 41 48 56 68  80  83 103 112 135 157 169 178
#> 33    3    36 39 48 61 76  98 116 145 166 198 227 225 220
#> 34    3    31 42 53 62 73  85 102 123 138 170 204 235 256
#> 35    3    39 42 50 61 78  89 109 130 146 170 214 250 272
#> 36    3    38 41 49 61 74  98 109 128 154 192 232 280 290
#> 37    3    32 41 49 65 82 107 129 159 179 221 263 291 305
#> 38    3    40 41 55 66 79 101 120 154 182 215 262 295 321
#> 39    3    34 41 49 63 85 107 134 164 186 235 294 327 341
#> 40    3    35 41 53 64 87 123 158 201 238 287 332 361 373
#> 41    4    44 42 51 65 86 103 118 127 138 145 146  NA  NA
#> 42    4    45 41 50 61 78  98 117 135 141 147 174 197 196
#> 43    4    43 42 55 69 96 131 157 184 188 197 198 199 200
#> 44    4    41 42 51 66 85 103 124 155 153 175 184 199 204
#> 45    4    47 41 53 66 79 100 123 148 157 168 185 210 205
#> 46    4    49 40 53 64 85 108 128 152 166 184 203 233 237
#> 47    4    46 40 52 62 82 101 120 144 156 173 210 231 238
#> 48    4    50 41 54 67 84 105 122 155 175 205 234 264 264
#> 49    4    42 42 49 63 84 103 126 160 174 204 234 269 281
#> 50    4    48 39 50 62 80 104 125 154 170 222 261 303 322
chick_m %tb>% .[`{time}` = value, .by = s(diet,chick)]
#>    diet chick  0  2  4  6   8  10  12  14  16  18  20  21
#> 1     1     1 42 51 59 64  76  93 106 125 149 171 199 205
#> 2     1     2 40 49 58 72  84 103 122 138 162 187 209 215
#> 3     1     3 43 39 55 67  84  99 115 138 163 187 198 202
#> 4     1     4 42 49 56 67  74  87 102 108 136 154 160 157
#> 5     1     5 41 42 48 60  79 106 141 164 197 199 220 223
#> 6     1     6 41 49 59 74  97 124 141 148 155 160 160 157
#> 7     1     7 41 49 57 71  89 112 146 174 218 250 288 305
#> 8     1     8 42 50 61 71  84  93 110 116 126 134 125  NA
#> 9     1     9 42 51 59 68  85  96  90  92  93 100 100  98
#> 10    1    10 41 44 52 63  74  81  89  96 101 112 120 124
#> 11    1    11 43 51 63 84 112 139 168 177 182 184 181 175
#> 12    1    12 41 49 56 62  72  88 119 135 162 185 195 205
#> 13    1    13 41 48 53 60  65  67  71  70  71  81  91  96
#> 14    1    14 41 49 62 79 101 128 164 192 227 248 259 266
#> 15    1    15 41 49 56 64  68  68  67  68  NA  NA  NA  NA
#> 16    1    16 41 45 49 51  57  51  54  NA  NA  NA  NA  NA
#> 17    1    17 42 51 61 72  83  89  98 103 113 123 133 142
#> 18    1    18 39 35 NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 19    1    19 43 48 55 62  65  71  82  88 106 120 144 157
#> 20    1    20 41 47 54 58  65  73  77  89  98 107 115 117
#> 21    2    21 40 50 62 86 125 163 217 240 275 307 318 331
#> 22    2    22 41 55 64 77  90  95 108 111 131 148 164 167
#> 23    2    23 43 52 61 73  90 103 127 135 145 163 170 175
#> 24    2    24 42 52 58 74  66  68  70  71  72  72  76  74
#> 25    2    25 40 49 62 78 102 124 146 164 197 231 259 265
#> 26    2    26 42 48 57 74  93 114 136 147 169 205 236 251
#> 27    2    27 39 46 58 73  87 100 115 123 144 163 185 192
#> 28    2    28 39 46 58 73  92 114 145 156 184 207 212 233
#> 29    2    29 39 48 59 74  87 106 134 150 187 230 279 309
#> 30    2    30 42 48 59 72  85  98 115 122 143 151 157 150
#> 31    3    31 42 53 62 73  85 102 123 138 170 204 235 256
#> 32    3    32 41 49 65 82 107 129 159 179 221 263 291 305
#> 33    3    33 39 50 63 77  96 111 137 144 151 146 156 147
#> 34    3    34 41 49 63 85 107 134 164 186 235 294 327 341
#> 35    3    35 41 53 64 87 123 158 201 238 287 332 361 373
#> 36    3    36 39 48 61 76  98 116 145 166 198 227 225 220
#> 37    3    37 41 48 56 68  80  83 103 112 135 157 169 178
#> 38    3    38 41 49 61 74  98 109 128 154 192 232 280 290
#> 39    3    39 42 50 61 78  89 109 130 146 170 214 250 272
#> 40    3    40 41 55 66 79 101 120 154 182 215 262 295 321
#> 41    4    41 42 51 66 85 103 124 155 153 175 184 199 204
#> 42    4    42 42 49 63 84 103 126 160 174 204 234 269 281
#> 43    4    43 42 55 69 96 131 157 184 188 197 198 199 200
#> 44    4    44 42 51 65 86 103 118 127 138 145 146  NA  NA
#> 45    4    45 41 50 61 78  98 117 135 141 147 174 197 196
#> 46    4    46 40 52 62 82 101 120 144 156 173 210 231 238
#> 47    4    47 41 53 66 79 100 123 148 157 168 185 210 205
#> 48    4    48 39 50 62 80 104 125 154 170 222 261 303 322
#> 49    4    49 40 53 64 85 108 128 152 166 184 203 233 237
#> 50    4    50 41 54 67 84 105 122 155 175 205 234 264 264

# tb doesn't support n dimensional arrays! just data frames
acast(chick_m, chick ~ time ~ diet)
#> , , 1
#> 
#>     0  2  4  6   8  10  12  14  16  18  20  21
#> 18 39 35 NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 16 41 45 49 51  57  51  54  NA  NA  NA  NA  NA
#> 15 41 49 56 64  68  68  67  68  NA  NA  NA  NA
#> 13 41 48 53 60  65  67  71  70  71  81  91  96
#> 9  42 51 59 68  85  96  90  92  93 100 100  98
#> 20 41 47 54 58  65  73  77  89  98 107 115 117
#> 10 41 44 52 63  74  81  89  96 101 112 120 124
#> 8  42 50 61 71  84  93 110 116 126 134 125  NA
#> 17 42 51 61 72  83  89  98 103 113 123 133 142
#> 19 43 48 55 62  65  71  82  88 106 120 144 157
#> 4  42 49 56 67  74  87 102 108 136 154 160 157
#> 6  41 49 59 74  97 124 141 148 155 160 160 157
#> 11 43 51 63 84 112 139 168 177 182 184 181 175
#> 3  43 39 55 67  84  99 115 138 163 187 198 202
#> 1  42 51 59 64  76  93 106 125 149 171 199 205
#> 12 41 49 56 62  72  88 119 135 162 185 195 205
#> 2  40 49 58 72  84 103 122 138 162 187 209 215
#> 5  41 42 48 60  79 106 141 164 197 199 220 223
#> 14 41 49 62 79 101 128 164 192 227 248 259 266
#> 7  41 49 57 71  89 112 146 174 218 250 288 305
#> 24 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 30 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 22 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 23 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 27 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 28 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 26 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 25 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 29 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 21 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 33 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 37 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 36 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 31 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 39 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 38 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 32 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 40 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 34 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 35 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 44 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 45 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 43 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 41 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 47 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 49 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 46 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 50 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 42 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 48 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 
#> , , 2
#> 
#>     0  2  4  6   8  10  12  14  16  18  20  21
#> 18 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 16 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 15 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 13 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 9  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 20 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 10 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 8  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 17 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 19 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 4  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 6  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 11 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 3  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 1  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 12 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 2  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 5  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 14 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 7  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 24 42 52 58 74  66  68  70  71  72  72  76  74
#> 30 42 48 59 72  85  98 115 122 143 151 157 150
#> 22 41 55 64 77  90  95 108 111 131 148 164 167
#> 23 43 52 61 73  90 103 127 135 145 163 170 175
#> 27 39 46 58 73  87 100 115 123 144 163 185 192
#> 28 39 46 58 73  92 114 145 156 184 207 212 233
#> 26 42 48 57 74  93 114 136 147 169 205 236 251
#> 25 40 49 62 78 102 124 146 164 197 231 259 265
#> 29 39 48 59 74  87 106 134 150 187 230 279 309
#> 21 40 50 62 86 125 163 217 240 275 307 318 331
#> 33 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 37 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 36 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 31 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 39 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 38 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 32 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 40 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 34 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 35 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 44 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 45 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 43 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 41 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 47 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 49 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 46 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 50 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 42 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 48 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 
#> , , 3
#> 
#>     0  2  4  6   8  10  12  14  16  18  20  21
#> 18 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 16 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 15 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 13 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 9  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 20 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 10 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 8  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 17 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 19 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 4  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 6  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 11 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 3  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 1  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 12 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 2  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 5  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 14 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 7  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 24 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 30 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 22 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 23 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 27 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 28 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 26 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 25 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 29 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 21 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 33 39 50 63 77  96 111 137 144 151 146 156 147
#> 37 41 48 56 68  80  83 103 112 135 157 169 178
#> 36 39 48 61 76  98 116 145 166 198 227 225 220
#> 31 42 53 62 73  85 102 123 138 170 204 235 256
#> 39 42 50 61 78  89 109 130 146 170 214 250 272
#> 38 41 49 61 74  98 109 128 154 192 232 280 290
#> 32 41 49 65 82 107 129 159 179 221 263 291 305
#> 40 41 55 66 79 101 120 154 182 215 262 295 321
#> 34 41 49 63 85 107 134 164 186 235 294 327 341
#> 35 41 53 64 87 123 158 201 238 287 332 361 373
#> 44 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 45 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 43 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 41 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 47 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 49 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 46 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 50 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 42 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 48 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 
#> , , 4
#> 
#>     0  2  4  6   8  10  12  14  16  18  20  21
#> 18 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 16 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 15 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 13 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 9  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 20 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 10 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 8  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 17 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 19 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 4  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 6  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 11 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 3  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 1  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 12 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 2  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 5  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 14 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 7  NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 24 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 30 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 22 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 23 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 27 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 28 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 26 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 25 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 29 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 21 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 33 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 37 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 36 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 31 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 39 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 38 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 32 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 40 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 34 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 35 NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 44 42 51 65 86 103 118 127 138 145 146  NA  NA
#> 45 41 50 61 78  98 117 135 141 147 174 197 196
#> 43 42 55 69 96 131 157 184 188 197 198 199 200
#> 41 42 51 66 85 103 124 155 153 175 184 199 204
#> 47 41 53 66 79 100 123 148 157 168 185 210 205
#> 49 40 53 64 85 108 128 152 166 184 203 233 237
#> 46 40 52 62 82 101 120 144 156 173 210 231 238
#> 50 41 54 67 84 105 122 155 175 205 234 264 264
#> 42 42 49 63 84 103 126 160 174 204 234 269 281
#> 48 39 50 62 80 104 125 154 170 222 261 303 322
# it gets a bit repetitive here
acast(chick_m, diet + chick ~ time, length, margins="diet")
#>              0  2  4  6  8 10 12 14 16 18 20 21
#> 1_18         1  1  0  0  0  0  0  0  0  0  0  0
#> 1_16         1  1  1  1  1  1  1  0  0  0  0  0
#> 1_15         1  1  1  1  1  1  1  1  0  0  0  0
#> 1_13         1  1  1  1  1  1  1  1  1  1  1  1
#> 1_9          1  1  1  1  1  1  1  1  1  1  1  1
#> 1_20         1  1  1  1  1  1  1  1  1  1  1  1
#> 1_10         1  1  1  1  1  1  1  1  1  1  1  1
#> 1_8          1  1  1  1  1  1  1  1  1  1  1  0
#> 1_17         1  1  1  1  1  1  1  1  1  1  1  1
#> 1_19         1  1  1  1  1  1  1  1  1  1  1  1
#> 1_4          1  1  1  1  1  1  1  1  1  1  1  1
#> 1_6          1  1  1  1  1  1  1  1  1  1  1  1
#> 1_11         1  1  1  1  1  1  1  1  1  1  1  1
#> 1_3          1  1  1  1  1  1  1  1  1  1  1  1
#> 1_1          1  1  1  1  1  1  1  1  1  1  1  1
#> 1_12         1  1  1  1  1  1  1  1  1  1  1  1
#> 1_2          1  1  1  1  1  1  1  1  1  1  1  1
#> 1_5          1  1  1  1  1  1  1  1  1  1  1  1
#> 1_14         1  1  1  1  1  1  1  1  1  1  1  1
#> 1_7          1  1  1  1  1  1  1  1  1  1  1  1
#> 2_24         1  1  1  1  1  1  1  1  1  1  1  1
#> 2_30         1  1  1  1  1  1  1  1  1  1  1  1
#> 2_22         1  1  1  1  1  1  1  1  1  1  1  1
#> 2_23         1  1  1  1  1  1  1  1  1  1  1  1
#> 2_27         1  1  1  1  1  1  1  1  1  1  1  1
#> 2_28         1  1  1  1  1  1  1  1  1  1  1  1
#> 2_26         1  1  1  1  1  1  1  1  1  1  1  1
#> 2_25         1  1  1  1  1  1  1  1  1  1  1  1
#> 2_29         1  1  1  1  1  1  1  1  1  1  1  1
#> 2_21         1  1  1  1  1  1  1  1  1  1  1  1
#> 3_33         1  1  1  1  1  1  1  1  1  1  1  1
#> 3_37         1  1  1  1  1  1  1  1  1  1  1  1
#> 3_36         1  1  1  1  1  1  1  1  1  1  1  1
#> 3_31         1  1  1  1  1  1  1  1  1  1  1  1
#> 3_39         1  1  1  1  1  1  1  1  1  1  1  1
#> 3_38         1  1  1  1  1  1  1  1  1  1  1  1
#> 3_32         1  1  1  1  1  1  1  1  1  1  1  1
#> 3_40         1  1  1  1  1  1  1  1  1  1  1  1
#> 3_34         1  1  1  1  1  1  1  1  1  1  1  1
#> 3_35         1  1  1  1  1  1  1  1  1  1  1  1
#> 4_44         1  1  1  1  1  1  1  1  1  1  0  0
#> 4_45         1  1  1  1  1  1  1  1  1  1  1  1
#> 4_43         1  1  1  1  1  1  1  1  1  1  1  1
#> 4_41         1  1  1  1  1  1  1  1  1  1  1  1
#> 4_47         1  1  1  1  1  1  1  1  1  1  1  1
#> 4_49         1  1  1  1  1  1  1  1  1  1  1  1
#> 4_46         1  1  1  1  1  1  1  1  1  1  1  1
#> 4_50         1  1  1  1  1  1  1  1  1  1  1  1
#> 4_42         1  1  1  1  1  1  1  1  1  1  1  1
#> 4_48         1  1  1  1  1  1  1  1  1  1  1  1
#> (all)_(all) 50 50 49 49 49 49 49 48 47 47 46 45
acast(chick_m, diet + chick ~ time, length, drop = FALSE)
#>      0 2 4 6 8 10 12 14 16 18 20 21
#> 1_18 1 1 0 0 0  0  0  0  0  0  0  0
#> 1_16 1 1 1 1 1  1  1  0  0  0  0  0
#> 1_15 1 1 1 1 1  1  1  1  0  0  0  0
#> 1_13 1 1 1 1 1  1  1  1  1  1  1  1
#> 1_9  1 1 1 1 1  1  1  1  1  1  1  1
#> 1_20 1 1 1 1 1  1  1  1  1  1  1  1
#> 1_10 1 1 1 1 1  1  1  1  1  1  1  1
#> 1_8  1 1 1 1 1  1  1  1  1  1  1  0
#> 1_17 1 1 1 1 1  1  1  1  1  1  1  1
#> 1_19 1 1 1 1 1  1  1  1  1  1  1  1
#> 1_4  1 1 1 1 1  1  1  1  1  1  1  1
#> 1_6  1 1 1 1 1  1  1  1  1  1  1  1
#> 1_11 1 1 1 1 1  1  1  1  1  1  1  1
#> 1_3  1 1 1 1 1  1  1  1  1  1  1  1
#> 1_1  1 1 1 1 1  1  1  1  1  1  1  1
#> 1_12 1 1 1 1 1  1  1  1  1  1  1  1
#> 1_2  1 1 1 1 1  1  1  1  1  1  1  1
#> 1_5  1 1 1 1 1  1  1  1  1  1  1  1
#> 1_14 1 1 1 1 1  1  1  1  1  1  1  1
#> 1_7  1 1 1 1 1  1  1  1  1  1  1  1
#> 1_24 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_30 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_22 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_23 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_27 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_28 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_26 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_25 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_29 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_21 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_33 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_37 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_36 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_31 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_39 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_38 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_32 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_40 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_34 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_35 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_44 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_45 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_43 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_41 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_47 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_49 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_46 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_50 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_42 0 0 0 0 0  0  0  0  0  0  0  0
#> 1_48 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_18 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_16 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_15 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_13 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_9  0 0 0 0 0  0  0  0  0  0  0  0
#> 2_20 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_10 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_8  0 0 0 0 0  0  0  0  0  0  0  0
#> 2_17 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_19 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_4  0 0 0 0 0  0  0  0  0  0  0  0
#> 2_6  0 0 0 0 0  0  0  0  0  0  0  0
#> 2_11 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_3  0 0 0 0 0  0  0  0  0  0  0  0
#> 2_1  0 0 0 0 0  0  0  0  0  0  0  0
#> 2_12 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_2  0 0 0 0 0  0  0  0  0  0  0  0
#> 2_5  0 0 0 0 0  0  0  0  0  0  0  0
#> 2_14 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_7  0 0 0 0 0  0  0  0  0  0  0  0
#> 2_24 1 1 1 1 1  1  1  1  1  1  1  1
#> 2_30 1 1 1 1 1  1  1  1  1  1  1  1
#> 2_22 1 1 1 1 1  1  1  1  1  1  1  1
#> 2_23 1 1 1 1 1  1  1  1  1  1  1  1
#> 2_27 1 1 1 1 1  1  1  1  1  1  1  1
#> 2_28 1 1 1 1 1  1  1  1  1  1  1  1
#> 2_26 1 1 1 1 1  1  1  1  1  1  1  1
#> 2_25 1 1 1 1 1  1  1  1  1  1  1  1
#> 2_29 1 1 1 1 1  1  1  1  1  1  1  1
#> 2_21 1 1 1 1 1  1  1  1  1  1  1  1
#> 2_33 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_37 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_36 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_31 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_39 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_38 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_32 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_40 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_34 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_35 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_44 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_45 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_43 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_41 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_47 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_49 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_46 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_50 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_42 0 0 0 0 0  0  0  0  0  0  0  0
#> 2_48 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_18 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_16 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_15 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_13 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_9  0 0 0 0 0  0  0  0  0  0  0  0
#> 3_20 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_10 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_8  0 0 0 0 0  0  0  0  0  0  0  0
#> 3_17 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_19 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_4  0 0 0 0 0  0  0  0  0  0  0  0
#> 3_6  0 0 0 0 0  0  0  0  0  0  0  0
#> 3_11 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_3  0 0 0 0 0  0  0  0  0  0  0  0
#> 3_1  0 0 0 0 0  0  0  0  0  0  0  0
#> 3_12 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_2  0 0 0 0 0  0  0  0  0  0  0  0
#> 3_5  0 0 0 0 0  0  0  0  0  0  0  0
#> 3_14 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_7  0 0 0 0 0  0  0  0  0  0  0  0
#> 3_24 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_30 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_22 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_23 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_27 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_28 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_26 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_25 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_29 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_21 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_33 1 1 1 1 1  1  1  1  1  1  1  1
#> 3_37 1 1 1 1 1  1  1  1  1  1  1  1
#> 3_36 1 1 1 1 1  1  1  1  1  1  1  1
#> 3_31 1 1 1 1 1  1  1  1  1  1  1  1
#> 3_39 1 1 1 1 1  1  1  1  1  1  1  1
#> 3_38 1 1 1 1 1  1  1  1  1  1  1  1
#> 3_32 1 1 1 1 1  1  1  1  1  1  1  1
#> 3_40 1 1 1 1 1  1  1  1  1  1  1  1
#> 3_34 1 1 1 1 1  1  1  1  1  1  1  1
#> 3_35 1 1 1 1 1  1  1  1  1  1  1  1
#> 3_44 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_45 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_43 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_41 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_47 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_49 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_46 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_50 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_42 0 0 0 0 0  0  0  0  0  0  0  0
#> 3_48 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_18 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_16 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_15 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_13 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_9  0 0 0 0 0  0  0  0  0  0  0  0
#> 4_20 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_10 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_8  0 0 0 0 0  0  0  0  0  0  0  0
#> 4_17 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_19 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_4  0 0 0 0 0  0  0  0  0  0  0  0
#> 4_6  0 0 0 0 0  0  0  0  0  0  0  0
#> 4_11 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_3  0 0 0 0 0  0  0  0  0  0  0  0
#> 4_1  0 0 0 0 0  0  0  0  0  0  0  0
#> 4_12 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_2  0 0 0 0 0  0  0  0  0  0  0  0
#> 4_5  0 0 0 0 0  0  0  0  0  0  0  0
#> 4_14 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_7  0 0 0 0 0  0  0  0  0  0  0  0
#> 4_24 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_30 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_22 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_23 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_27 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_28 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_26 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_25 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_29 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_21 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_33 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_37 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_36 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_31 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_39 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_38 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_32 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_40 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_34 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_35 0 0 0 0 0  0  0  0  0  0  0  0
#> 4_44 1 1 1 1 1  1  1  1  1  1  0  0
#> 4_45 1 1 1 1 1  1  1  1  1  1  1  1
#> 4_43 1 1 1 1 1  1  1  1  1  1  1  1
#> 4_41 1 1 1 1 1  1  1  1  1  1  1  1
#> 4_47 1 1 1 1 1  1  1  1  1  1  1  1
#> 4_49 1 1 1 1 1  1  1  1  1  1  1  1
#> 4_46 1 1 1 1 1  1  1  1  1  1  1  1
#> 4_50 1 1 1 1 1  1  1  1  1  1  1  1
#> 4_42 1 1 1 1 1  1  1  1  1  1  1  1
#> 4_48 1 1 1 1 1  1  1  1  1  1  1  1

#Tips example
dcast(melt(tips), sex ~ smoker, mean, subset = .(variable == "total_bill"))
#> Using sex, smoker, day, time as id variables
#>      sex       No      Yes
#> 1 Female 18.10519 17.97788
#> 2   Male 19.79124 22.28450
melt(tips) %tb>% 
  .[variable == "total_bill", `{smoker}` = mean(value), .by = "sex"]
#> Using sex, smoker, day, time as id variables
#>      sex       No      Yes
#> 1 Female 18.10519 17.97788
#> 2   Male 19.79124 22.28450

# redundant still
ff_d <- melt(french_fries, id=1:4, na.rm=TRUE)
dcast(ff_d, subject ~ time, length)
#>    subject  1  2  3  4  5  6  7  8  9 10
#> 1        3 30 30 30 30 30 30 30 30 30  0
#> 2       10 30 30 30 30 30 30 30 30 30 30
#> 3       15 30 30 30 30 25 30 30 30 30 30
#> 4       16 30 30 30 30 30 30 30 29 30 30
#> 5       19 30 30 30 30 30 30 30 30 30 30
#> 6       31 30 30 30 30 30 30 30 30  0 30
#> 7       51 30 30 30 30 30 30 30 30 30 30
#> 8       52 30 30 30 30 30 30 30 30 30 30
#> 9       63 30 30 30 30 30 30 30 30 30 30
#> 10      78 30 30 30 30 30 30 30 30 30 30
#> 11      79 30 30 30 30 30 30 29 28 30  0
#> 12      86 30 30 30 30 30 30 30 30  0 30
ff_d %tb>% .[`{time}` = length(value), .by = "subject"]
#>    subject  1  2  3  4  5  6  7  8  9 10
#> 1        3 30 30 30 30 30 30 30 30 30 NA
#> 2       10 30 30 30 30 30 30 30 30 30 30
#> 3       15 30 30 30 30 25 30 30 30 30 30
#> 4       16 30 30 30 30 30 30 30 29 30 30
#> 5       19 30 30 30 30 30 30 30 30 30 30
#> 6       31 30 30 30 30 30 30 30 30 NA 30
#> 7       51 30 30 30 30 30 30 30 30 30 30
#> 8       52 30 30 30 30 30 30 30 30 30 30
#> 9       63 30 30 30 30 30 30 30 30 30 30
#> 10      78 30 30 30 30 30 30 30 30 30 30
#> 11      79 30 30 30 30 30 30 29 28 30 NA
#> 12      86 30 30 30 30 30 30 30 30 NA 30
ff_d %tb>% .[`{time}` = nrow(.subset), .by = "subject"]
#>    subject  1  2  3  4  5  6  7  8  9 10
#> 1        3 30 30 30 30 30 30 30 30 30 NA
#> 2       10 30 30 30 30 30 30 30 30 30 30
#> 3       15 30 30 30 30 25 30 30 30 30 30
#> 4       16 30 30 30 30 30 30 30 29 30 30
#> 5       19 30 30 30 30 30 30 30 30 30 30
#> 6       31 30 30 30 30 30 30 30 30 NA 30
#> 7       51 30 30 30 30 30 30 30 30 30 30
#> 8       52 30 30 30 30 30 30 30 30 30 30
#> 9       63 30 30 30 30 30 30 30 30 30 30
#> 10      78 30 30 30 30 30 30 30 30 30 30
#> 11      79 30 30 30 30 30 30 29 28 30 NA
#> 12      86 30 30 30 30 30 30 30 30 NA 30
# it doesn't convert NAs to 0, we might need a ".fill" argument for those

dcast(ff_d, treatment ~ variable, mean, margins = TRUE)
#>   treatment   potato  buttery    grassy   rancid   painty    (all)
#> 1         1 6.887931 1.780087 0.6491379 4.065517 2.583621 3.194478
#> 2         2 7.001724 1.973913 0.6629310 3.624569 2.455844 3.146413
#> 3         3 6.967965 1.717749 0.6805195 3.866667 2.525541 3.151688
#> 4     (all) 6.952518 1.823699 0.6641727 3.852230 2.521758 3.164218
dcast(ff_d, treatment + subject ~ variable, mean, margins="treatment")
#>    treatment subject    potato   buttery     grassy    rancid     painty
#> 1          1       3  6.216667 0.3722222 0.18888889 2.1055556 3.11111111
#> 2          1      10  9.955000 6.7500000 0.58500000 4.0200000 1.37500000
#> 3          1      15  3.360000 0.7200000 0.42000000 3.9650000 3.26000000
#> 4          1      16  6.495000 3.2600000 0.75500000 4.1200000 1.23000000
#> 5          1      19  9.385000 3.0550000 2.02000000 5.3600000 2.77500000
#> 6          1      31  8.844444 0.4444444 0.08888889 5.9444444 3.21111111
#> 7          1      51 10.675000 2.6400000 1.05000000 5.1500000 1.95500000
#> 8          1      52  5.060000 0.8050000 0.87500000 4.2850000 2.64500000
#> 9          1      63  6.775000 0.0250000 0.00000000 6.0550000 3.85500000
#> 10         1      78  3.620000 0.7350000 0.54000000 1.5050000 3.49000000
#> 11         1      79  8.061111 0.2823529 0.34444444 0.5666667 0.00000000
#> 12         1      86  4.183333 1.7722222 0.80555556 5.4944444 4.10555556
#> 13         2       3  6.738889 0.5888889 0.10555556 3.1388889 2.47777778
#> 14         2      10  9.995000 6.9800000 0.47500000 2.1500000 0.82000000
#> 15         2      15  4.405000 1.3150000 0.34000000 2.2850000 2.06000000
#> 16         2      16  6.450000 3.3736842 1.05500000 3.4000000 0.45500000
#> 17         2      19  8.640000 2.4500000 1.13500000 5.4050000 4.15500000
#> 18         2      31  8.033333 0.6166667 0.15555556 6.0500000 5.06111111
#> 19         2      51  9.985000 3.7950000 1.57000000 4.6700000 2.25500000
#> 20         2      52  5.515000 1.0250000 1.18000000 4.2250000 2.19500000
#> 21         2      63  8.415000 0.1050000 0.01000000 5.0900000 4.35500000
#> 22         2      78  3.780000 0.2950000 0.75500000 1.5500000 2.72500000
#> 23         2      79  7.938889 0.6941176 0.25555556 1.0333333 0.00000000
#> 24         2      86  3.994444 2.0611111 0.78333333 4.5222222 2.84444444
#> 25         3       3  5.294444 0.7666667 0.09444444 2.8555556 2.86666667
#> 26         3      10 10.030000 6.4500000 0.14500000 3.1100000 0.69000000
#> 27         3      15  3.963158 0.9894737 0.44210526 2.5473684 2.36842105
#> 28         3      16  6.860000 2.7000000 1.12500000 3.2000000 0.55500000
#> 29         3      19  8.740000 1.7250000 2.07000000 7.2400000 3.90500000
#> 30         3      31  9.027778 0.6500000 0.17222222 6.5777778 5.12777778
#> 31         3      51 10.220000 3.1300000 1.35000000 4.9150000 2.54500000
#> 32         3      52  5.475000 0.8650000 0.76500000 3.1600000 2.66000000
#> 33         3      63  8.060000 0.0650000 0.12500000 6.1850000 3.10000000
#> 34         3      78  4.000000 0.7050000 0.66500000 1.1850000 3.52000000
#> 35         3      79  7.733333 0.5722222 0.11666667 1.1777778 0.02777778
#> 36         3      86  3.866667 1.6333333 0.94444444 4.1055556 3.02777778
#> 37     (all)   (all)  6.952518 1.8236994 0.66417266 3.8522302 2.52175793
if (require("lattice")) {
  lattice::xyplot(`1` ~ `2` | variable, dcast(ff_d, ... ~ rep), aspect="iso")
}
#> Loading required package: lattice

Created on 2020-01-27 by the reprex package (v0.3.0)

moodymudskipper commented 4 years ago

examples from pivot_wider() :

library(tidyr)
library(tb)

fish_encounters
#> # A tibble: 114 x 3
#>    fish  station  seen
#>    <fct> <fct>   <int>
#>  1 4842  Release     1
#>  2 4842  I80_1       1
#>  3 4842  Lisbon      1
#>  4 4842  Rstr        1
#>  5 4842  Base_TD     1
#>  6 4842  BCE         1
#>  7 4842  BCW         1
#>  8 4842  BCE2        1
#>  9 4842  BCW2        1
#> 10 4842  MAE         1
#> # … with 104 more rows
fish_encounters %>%
  pivot_wider(names_from = station, values_from = seen)
#> # A tibble: 19 x 12
#>    fish  Release I80_1 Lisbon  Rstr Base_TD   BCE   BCW  BCE2  BCW2   MAE   MAW
#>    <fct>   <int> <int>  <int> <int>   <int> <int> <int> <int> <int> <int> <int>
#>  1 4842        1     1      1     1       1     1     1     1     1     1     1
#>  2 4843        1     1      1     1       1     1     1     1     1     1     1
#>  3 4844        1     1      1     1       1     1     1     1     1     1     1
#>  4 4845        1     1      1     1       1    NA    NA    NA    NA    NA    NA
#>  5 4847        1     1      1    NA      NA    NA    NA    NA    NA    NA    NA
#>  6 4848        1     1      1     1      NA    NA    NA    NA    NA    NA    NA
#>  7 4849        1     1     NA    NA      NA    NA    NA    NA    NA    NA    NA
#>  8 4850        1     1     NA     1       1     1     1    NA    NA    NA    NA
#>  9 4851        1     1     NA    NA      NA    NA    NA    NA    NA    NA    NA
#> 10 4854        1     1     NA    NA      NA    NA    NA    NA    NA    NA    NA
#> 11 4855        1     1      1     1       1    NA    NA    NA    NA    NA    NA
#> 12 4857        1     1      1     1       1     1     1     1     1    NA    NA
#> 13 4858        1     1      1     1       1     1     1     1     1     1     1
#> 14 4859        1     1      1     1       1    NA    NA    NA    NA    NA    NA
#> 15 4861        1     1      1     1       1     1     1     1     1     1     1
#> 16 4862        1     1      1     1       1     1     1     1     1    NA    NA
#> 17 4863        1     1     NA    NA      NA    NA    NA    NA    NA    NA    NA
#> 18 4864        1     1     NA    NA      NA    NA    NA    NA    NA    NA    NA
#> 19 4865        1     1      1    NA      NA    NA    NA    NA    NA    NA    NA
fish_encounters %tb>% .[`{station}` = seen, .by = "fish"]
#> # A tibble: 19 x 12
#>    fish  Release I80_1 Lisbon  Rstr Base_TD   BCE   BCW  BCE2  BCW2   MAE   MAW
#>    <fct>   <int> <int>  <int> <int>   <int> <int> <int> <int> <int> <int> <int>
#>  1 4842        1     1      1     1       1     1     1     1     1     1     1
#>  2 4843        1     1      1     1       1     1     1     1     1     1     1
#>  3 4844        1     1      1     1       1     1     1     1     1     1     1
#>  4 4845        1     1      1     1       1    NA    NA    NA    NA    NA    NA
#>  5 4847        1     1      1    NA      NA    NA    NA    NA    NA    NA    NA
#>  6 4848        1     1      1     1      NA    NA    NA    NA    NA    NA    NA
#>  7 4849        1     1     NA    NA      NA    NA    NA    NA    NA    NA    NA
#>  8 4850        1     1     NA     1       1     1     1    NA    NA    NA    NA
#>  9 4851        1     1     NA    NA      NA    NA    NA    NA    NA    NA    NA
#> 10 4854        1     1     NA    NA      NA    NA    NA    NA    NA    NA    NA
#> 11 4855        1     1      1     1       1    NA    NA    NA    NA    NA    NA
#> 12 4857        1     1      1     1       1     1     1     1     1    NA    NA
#> 13 4858        1     1      1     1       1     1     1     1     1     1     1
#> 14 4859        1     1      1     1       1    NA    NA    NA    NA    NA    NA
#> 15 4861        1     1      1     1       1     1     1     1     1     1     1
#> 16 4862        1     1      1     1       1     1     1     1     1    NA    NA
#> 17 4863        1     1     NA    NA      NA    NA    NA    NA    NA    NA    NA
#> 18 4864        1     1     NA    NA      NA    NA    NA    NA    NA    NA    NA
#> 19 4865        1     1      1    NA      NA    NA    NA    NA    NA    NA    NA

# Fill in missing values
fish_encounters %>%
  pivot_wider(
    names_from = station,
    values_from = seen,
    values_fill = list(seen = 0)
  )
#> # A tibble: 19 x 12
#>    fish  Release I80_1 Lisbon  Rstr Base_TD   BCE   BCW  BCE2  BCW2   MAE   MAW
#>    <fct>   <int> <int>  <int> <int>   <int> <int> <int> <int> <int> <int> <int>
#>  1 4842        1     1      1     1       1     1     1     1     1     1     1
#>  2 4843        1     1      1     1       1     1     1     1     1     1     1
#>  3 4844        1     1      1     1       1     1     1     1     1     1     1
#>  4 4845        1     1      1     1       1     0     0     0     0     0     0
#>  5 4847        1     1      1     0       0     0     0     0     0     0     0
#>  6 4848        1     1      1     1       0     0     0     0     0     0     0
#>  7 4849        1     1      0     0       0     0     0     0     0     0     0
#>  8 4850        1     1      0     1       1     1     1     0     0     0     0
#>  9 4851        1     1      0     0       0     0     0     0     0     0     0
#> 10 4854        1     1      0     0       0     0     0     0     0     0     0
#> 11 4855        1     1      1     1       1     0     0     0     0     0     0
#> 12 4857        1     1      1     1       1     1     1     1     1     0     0
#> 13 4858        1     1      1     1       1     1     1     1     1     1     1
#> 14 4859        1     1      1     1       1     0     0     0     0     0     0
#> 15 4861        1     1      1     1       1     1     1     1     1     1     1
#> 16 4862        1     1      1     1       1     1     1     1     1     0     0
#> 17 4863        1     1      0     0       0     0     0     0     0     0     0
#> 18 4864        1     1      0     0       0     0     0     0     0     0     0
#> 19 4865        1     1      1     0       0     0     0     0     0     0     0
#== will be :
# fish_encounters %tb>% .[`{station}` = seen, .by = "fish", .fill= list(seen = 0)
# note: this would work too but might be confusing : 
# fish_encounters %tb>% .[`{station}` = seen ? 0, .by = "fish"]

# Generate column names from multiple variables
us_rent_income %>%
  pivot_wider(names_from = variable, values_from = c(estimate, moe))
#> # A tibble: 52 x 6
#>    GEOID NAME                 estimate_income estimate_rent moe_income moe_rent
#>    <chr> <chr>                          <dbl>         <dbl>      <dbl>    <dbl>
#>  1 01    Alabama                        24476           747        136        3
#>  2 02    Alaska                         32940          1200        508       13
#>  3 04    Arizona                        27517           972        148        4
#>  4 05    Arkansas                       23789           709        165        5
#>  5 06    California                     29454          1358        109        3
#>  6 08    Colorado                       32401          1125        109        5
#>  7 09    Connecticut                    35326          1123        195        5
#>  8 10    Delaware                       31560          1076        247       10
#>  9 11    District of Columbia           43198          1424        681       17
#> 10 12    Florida                        25952          1077         70        3
#> # … with 42 more rows

# we don't have the multi spread with "multi values" ...
us_rent_income %tb>%
  .[`estimate_{variable}` = estimate, `moe_{variable}` = moe, .by = "GEOID"]
#> # A tibble: 52 x 5
#>    GEOID estimate_income estimate_rent moe_income moe_rent
#>    <chr>           <dbl>         <dbl>      <dbl>    <dbl>
#>  1 01              24476           747        136        3
#>  2 02              32940          1200        508       13
#>  3 04              27517           972        148        4
#>  4 05              23789           709        165        5
#>  5 06              29454          1358        109        3
#>  6 08              32401          1125        109        5
#>  7 09              35326          1123        195        5
#>  8 10              31560          1076        247       10
#>  9 11              43198          1424        681       17
#> 10 12              25952          1077         70        3
#> # … with 42 more rows

# Can perform aggregation with values_fn
warpbreaks <- as_tibble(warpbreaks[c("wool", "tension", "breaks")])
warpbreaks
#> # A tibble: 54 x 3
#>    wool  tension breaks
#>    <fct> <fct>    <dbl>
#>  1 A     L           26
#>  2 A     L           30
#>  3 A     L           54
#>  4 A     L           25
#>  5 A     L           70
#>  6 A     L           52
#>  7 A     L           51
#>  8 A     L           26
#>  9 A     L           67
#> 10 A     M           18
#> # … with 44 more rows
warpbreaks %>%
  pivot_wider(
    names_from = wool,
    values_from = breaks,
    values_fn = list(breaks = mean)
  )
#> # A tibble: 3 x 3
#>   tension     A     B
#>   <fct>   <dbl> <dbl>
#> 1 L        44.6  28.2
#> 2 M        24    28.8
#> 3 H        24.6  18.8
warpbreaks %tb>%
  .[`{wool}` = mean(breaks), .by = "tension"]
#> # A tibble: 3 x 3
#>   tension     A     B
#>   <fct>   <dbl> <dbl>
#> 1 L        44.6  28.2
#> 2 M        24    28.8
#> 3 H        24.6  18.8

Created on 2020-01-27 by the reprex package (v0.3.0)

moodymudskipper commented 4 years ago

I think now .index should be done after all transformations, that's easier to understand, and it's easy to do :

mini_iris %tb>%
  .[.index = ~ Species][{key} = "flower_att", {value} = "measurement"]
moodymudskipper commented 4 years ago

this doesn't support "mutli- gather" though, but multi gather is not a tidy operation,

We'd have Species, Sepal_key, Sepal_value, Petal_key, Petal_value, but unlest these are nested, we lose the id so we lose the send.

Which makes me think an index() function still makes sense, and the index parameter can be wrapped around it, then on top of this, user could unnest if they want to.

moodymudskipper commented 4 years ago

handling multi spread from reshape example, we already have the following equivalents :

df <- data.frame(id = rep(1:4, rep(2,4)),
                 visit = I(rep(c("Before","After"), 4)),
                 x = rnorm(4), y = runif(4))
reshape(df, timevar = "visit", idvar = "id", direction = "wide")
df %tb>%   .[`x.{visit}` = x, `y.{visit}` = y, by = "id"]

But the latter is redundant and can be improved, what about :

df %tb>% .[`{.}.{visit}` = s(x, y)]

s() works well in this case, we should just expect a selection object if we find {.} in the name.

We could also rename on the fly :

df %tb>% .[`{.}.{visit}` = s(X = x, Y = y)]

Or use complex selections etc.

BUT it doesn't really work if I need aggregation, e.g. if I want to do :

df %tb>% .[`{.}.{visit}` = s(mean_x = mean(x),  median_y = median(y))]

To get columns id mean_x .Before median_y .Before mean_x .After median_y.After

In fact maybe we need agg() as an equivalent to s() for aggregation, it would share some features but none would be a pure subset of the other.

Though maybe for this case however it seems ok to write:

df %tb>% .[`mean_x.{visit}` = mean(x),  `median_y.{visit}` = median(y))]

We miss a compact syntax however to apply the same function on all :

df %tb>% .[`mean_x.{visit}` = mean(x),  `mean_y.{visit}` = mean(y))]

and to apply several functions on one :

df %tb>% .[`mean_x.{visit}` = mean(x),  `median_x.{visit}` = median(x))]

I think all these cases need to be laid out on a white board, we might need to rework a "universal" approach if possible. Would be good to make sure it handles every corner case that other reshaping functions handle

moodymudskipper commented 4 years ago
df %tb>% .[`mean_x.{visit}` = mean(x),  `mean_y.{visit}` = mean(y))]

can be written :

df %tb>% .[`mean_<x>.{visit}` = mean(.),  `mean_<y>.{visit}` = mean(.))]
df %tb>% .[`mean_<s(x,y)>.{visit}` = median(.)]

where we surrround by <> the variable(s) to use on the rhs. I thought about using () too but the good thing about <> is that it can't be confused with something else and is unambiguous here.

We could have the oposite and have :

df %tb>% .[`<.>.{visit}` = s(mean_x = mean(x),  median_y = median(y))]

We see that in both cases the dot is used as a reference to the other side, this principle might apply more widely, so we can summarize with things like :

iris %tb>% .[`mean_<Sepal.Width>` = mean(.), by = Species]
iris %tb>% .[`mean_<?"^Sepal">` = mean(.), by = Species]
iris %tb>% .[`mean_<.>` = agg(SW = mean(Sepal.Width), SL = mean(Sepal.Length)),, by = Species]
iris %tb>% .[`mean_<s(SW = Sepal.Width, SL = Sepal.Length)>` = mean(.),, by = Species]

These could be equivalent :

df %tb>% .[`mean_x.{visit}` = mean(x),  `median_x.{visit}` = median(x))]
df %tb>% .[`<.>_<x>.{visit}` = agg(mean = mean(.), y = median(.))]
df %tb>% .[`<.>_<x>.{visit}` = agg(mean, median)]

but we see here that it starts to be confusing with dots having different meaning on each side.

Instead of <.> on the lhs, we can have *names* or *rhs_name*. When we reach this degree of complexity I think it's not about being compact anymore but offering maximum flexibility so maybe being explicit like this is good.

Because of the association of glue names with {} we could also reconsider the way we spread and use <> instead, and note that [] is free too, though it might be the most possibly confusing one.

{} around symbols can be used on the rhs that being said, so we could have a "link" between {.} on either side, and what's used on the other side.

moodymudskipper commented 4 years ago

I think I got index about right :

This will create key and value columns :

tb[index = s(this, that)]

This renames these afterwards, looks almost like regular arguments :

tb[index = s(this, that)][{key} = "new_key", `{value}` = "new_value"]

Another possibility :

tb[index = "<value_header>_<foo>_<bar>"]

will place the values under a column named as what is matched by <value_header>, and index by what is matched by <foo> and <bar>.

if the pattern doesn't include <value_header>, it'll be named value, if it doesn't include other terms there'll be only one matching the whole thing, and named key.

They can use glue syntax.

By default all other colums are kept, but we can use "along" notation to limit them, which might be more convenient than first subsetting j, which is possible as well.

moodymudskipper commented 4 years ago

Better call it stack than index, because we are effectively feeding the columns to stack, and it evokes utils::stack.

moodymudskipper commented 4 years ago

stack is implemented and tested on examples of all major reshaping packages except data.table

No formal tests so far and code is not super clean. Needs tests and most likely refactoring.

moodymudskipper commented 4 years ago

spread now uses <foo> rather than {foo}, so we can use {} for conventional gluing (not implemented yet)!

moodymudskipper commented 4 years ago

the only remaining thing is : https://github.com/moodymudskipper/tb/issues/37