Closed moodymudskipper closed 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)
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)
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
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)
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)
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"]
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.
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
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.
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.
Better call it stack
than index, because we are effectively feeding the columns to stack, and it evokes utils::stack
.
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.
spread now uses <foo>
rather than {foo}
, so we can use {}
for conventional gluing (not implemented yet)!
the only remaining thing is : https://github.com/moodymudskipper/tb/issues/37
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.