R/alkIndivAge.R
alkIndivAge.Rd
Use either the semi- or completely-random methods from Isermann and Knight (2005) to assign ages to individual fish in the unaged sample according to the information in an age-length key supplied by the user.
alkIndivAge(key, formula, data, type = c("SR", "CR"), breaks = NULL, seed = NULL)
key | A numeric matrix that contains the age-length key. The format of this matrix is important. See details. |
---|---|
formula | A formula of the form |
data | A data.frame that minimally contains the length measurements and possibly contains a variable that will receive the age assignments as given in |
type | A string that indicates whether to use the semi-random ( |
breaks | A numeric vector of lower values that define the length intervals. See details. |
seed | A single numeric that is given to |
The original data.frame in data
with assigned ages added to the column supplied in formula
or in an additional column labeled as age
. See details.
The age-length key in key
must have length intervals as rows and ages as columns. The row names of key
(i.e., rownames(key)
) must contain the minimum values of each length interval (e.g., if an interval is 100-109, then the corresponding row name must be 100). The column names of key
(i.e., colnames(key)
) must contain the age values (e.g., the columns can NOT be named with “age.1”, for example).
The length intervals in the rows of key
must contain all of the length intervals present in the unaged sample to which the age-length key is to be applied (i.e., sent in the length
portion of the formula
). If this constraint is not met, then the function will stop with an error message.
If breaks=NULL
, then the length intervals for the unaged sample will be determined with a starting interval at the minimum value of the row names in key
and a width of the length intervals as determined by the minimum difference in adjacent row names of key
. If length intervals of differing widths were used when constructing key
, then those breaks should be supplied to breaks=
. Use of breaks=
may be useful when “uneven” length interval widths were used because the lengths in the unaged sample are not fully represented in the aged sample. See the examples.
Assigned ages will be stored in the column identified on the left-hand-side of formula
(if the formula has both a left- and right-hand-side). If this variable is missing in formula
, then the new column will be labeled with age
.
The type="SR"
method worked perfectly on a small example. The type="SR"
method provides results that reasonably approximate the results from alkAgeDist
and alkMeanVar
, which suggests that the age assessments are reasonable.
5-Age-Length Key.
Ogle, D.H. 2016. Introductory Fisheries Analyses with R. Chapman & Hall/CRC, Boca Raton, FL.
Isermann, D.A. and C.T. Knight. 2005. A computer program for age-length keys incorporating age assignment to individual fish. North American Journal of Fisheries Management, 25:1153-1160. [Was (is?) from http://www.tandfonline.com/doi/abs/10.1577/M04-130.1.]
See alkAgeDist
and alkMeanVar
for alternative methods to derived age distributions and mean (and SD) values for each age. See alkPlot
for methods to visualize age-length keys.
## First Example -- Even breaks for length categories WR1 <- WR79 # add length categories (width=5) WR1$LCat <- lencat(WR1$len,w=5) # isolate aged and unaged samples WR1.age <- subset(WR1, !is.na(age)) WR1.len <- subset(WR1, is.na(age)) # note no ages in unaged sample head(WR1.len)#> ID len age LCat #> 1 1 37 NA 35 #> 2 2 37 NA 35 #> 3 3 39 NA 35 #> 4 4 37 NA 35 #> 7 7 42 NA 40 #> 8 8 42 NA 40# create age-length key raw <- xtabs(~LCat+age,data=WR1.age) ( WR1.key <- prop.table(raw, margin=1) )#> age #> LCat 4 5 6 7 8 9 #> 35 1.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 40 1.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 45 1.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 50 1.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 55 1.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 60 0.60000000 0.40000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 65 0.00000000 1.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 70 0.00000000 1.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 75 0.00000000 0.88888889 0.11111111 0.00000000 0.00000000 0.00000000 #> 80 0.00000000 0.25000000 0.75000000 0.00000000 0.00000000 0.00000000 #> 85 0.00000000 0.00000000 0.90909091 0.09090909 0.00000000 0.00000000 #> 90 0.00000000 0.00000000 0.26315789 0.63157895 0.10526316 0.00000000 #> 95 0.00000000 0.00000000 0.05882353 0.70588235 0.17647059 0.00000000 #> 100 0.00000000 0.00000000 0.00000000 0.55555556 0.16666667 0.27777778 #> 105 0.00000000 0.00000000 0.00000000 0.28571429 0.42857143 0.14285714 #> 110 0.00000000 0.00000000 0.00000000 0.20000000 0.20000000 0.20000000 #> 115 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> age #> LCat 10 11 #> 35 0.00000000 0.00000000 #> 40 0.00000000 0.00000000 #> 45 0.00000000 0.00000000 #> 50 0.00000000 0.00000000 #> 55 0.00000000 0.00000000 #> 60 0.00000000 0.00000000 #> 65 0.00000000 0.00000000 #> 70 0.00000000 0.00000000 #> 75 0.00000000 0.00000000 #> 80 0.00000000 0.00000000 #> 85 0.00000000 0.00000000 #> 90 0.00000000 0.00000000 #> 95 0.05882353 0.00000000 #> 100 0.00000000 0.00000000 #> 105 0.14285714 0.00000000 #> 110 0.20000000 0.20000000 #> 115 1.00000000 0.00000000# apply the age-length key WR1.len <- alkIndivAge(WR1.key,age~len,data=WR1.len) # now there are ages head(WR1.len)#> ID len age LCat #> 1 1 37 4 35 #> 2 2 37 4 35 #> 3 3 39 4 35 #> 4 4 37 4 35 #> 7 7 42 4 40 #> 8 8 42 4 40# combine orig age & new ages WR1.comb <- rbind(WR1.age, WR1.len) # mean length-at-age Summarize(len~age,data=WR1.comb,digits=2)#> age n mean sd min Q1 median Q3 max #> 1 4 987 51.86 5.14 35 48 52.0 56.00 64 #> 2 5 395 71.80 5.32 60 68 72.0 76.00 84 #> 3 6 271 86.75 4.80 75 83 87.0 89.00 98 #> 4 7 448 97.53 5.21 85 93 97.0 101.25 113 #> 5 8 145 101.32 5.91 90 96 102.0 107.00 113 #> 6 9 78 103.63 3.06 100 102 103.0 105.00 112 #> 7 10 39 104.92 7.10 95 97 106.0 109.50 119 #> 8 11 6 112.33 0.82 111 112 112.5 113.00 113# age frequency distribution ( af <- xtabs(~age,data=WR1.comb) )#> age #> 4 5 6 7 8 9 10 11 #> 987 395 271 448 145 78 39 6# proportional age distribution ( ap <- prop.table(af) )#> age #> 4 5 6 7 8 9 #> 0.416631490 0.166737020 0.114394259 0.189109329 0.061207260 0.032925285 #> 10 11 #> 0.016462642 0.002532714## Second Example -- length sample does not have an age variable WR2 <- WR79 # isolate age and unaged samples WR2.age <- subset(WR2, !is.na(age)) WR2.len <- subset(WR2, is.na(age)) # remove age variable (for demo only) WR2.len <- WR2.len[,-3] # add length categories to aged sample WR2.age$LCat <- lencat(WR2.age$len,w=5) # create age-length key raw <- xtabs(~LCat+age,data=WR2.age) ( WR2.key <- prop.table(raw, margin=1) )#> age #> LCat 4 5 6 7 8 9 #> 35 1.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 40 1.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 45 1.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 50 1.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 55 1.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 60 0.60000000 0.40000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 65 0.00000000 1.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 70 0.00000000 1.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 75 0.00000000 0.88888889 0.11111111 0.00000000 0.00000000 0.00000000 #> 80 0.00000000 0.25000000 0.75000000 0.00000000 0.00000000 0.00000000 #> 85 0.00000000 0.00000000 0.90909091 0.09090909 0.00000000 0.00000000 #> 90 0.00000000 0.00000000 0.26315789 0.63157895 0.10526316 0.00000000 #> 95 0.00000000 0.00000000 0.05882353 0.70588235 0.17647059 0.00000000 #> 100 0.00000000 0.00000000 0.00000000 0.55555556 0.16666667 0.27777778 #> 105 0.00000000 0.00000000 0.00000000 0.28571429 0.42857143 0.14285714 #> 110 0.00000000 0.00000000 0.00000000 0.20000000 0.20000000 0.20000000 #> 115 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> age #> LCat 10 11 #> 35 0.00000000 0.00000000 #> 40 0.00000000 0.00000000 #> 45 0.00000000 0.00000000 #> 50 0.00000000 0.00000000 #> 55 0.00000000 0.00000000 #> 60 0.00000000 0.00000000 #> 65 0.00000000 0.00000000 #> 70 0.00000000 0.00000000 #> 75 0.00000000 0.00000000 #> 80 0.00000000 0.00000000 #> 85 0.00000000 0.00000000 #> 90 0.00000000 0.00000000 #> 95 0.05882353 0.00000000 #> 100 0.00000000 0.00000000 #> 105 0.14285714 0.00000000 #> 110 0.20000000 0.20000000 #> 115 1.00000000 0.00000000# apply the age-length key WR2.len <- alkIndivAge(WR2.key,~len,data=WR2.len) # add length cat to length sample WR2.len$LCat <- lencat(WR2.len$len,w=5) head(WR2.len)#> ID len age LCat #> 1 1 37 4 35 #> 2 2 37 4 35 #> 3 3 39 4 35 #> 4 4 37 4 35 #> 7 7 42 4 40 #> 8 8 42 4 40# combine orig age & new ages WR2.comb <- rbind(WR2.age, WR2.len) Summarize(len~age,data=WR2.comb,digits=2)#> age n mean sd min Q1 median Q3 max #> 1 4 987 51.87 5.15 35 48 52 56.00 64 #> 2 5 395 71.74 5.30 60 68 72 76.00 84 #> 3 6 270 86.69 4.57 75 83 87 89.00 99 #> 4 7 448 97.62 5.14 85 93 97 102.00 113 #> 5 8 148 101.14 5.90 90 97 101 107.00 113 #> 6 9 77 103.77 3.22 100 102 103 105.00 114 #> 7 10 38 105.00 7.56 95 97 107 109.75 119 #> 8 11 6 111.33 1.03 110 111 111 111.75 113## Third Example -- Uneven breaks for length categories WR3 <- WR79 # set up uneven breaks brks <- c(seq(35,100,5),110,130) WR3$LCat <- lencat(WR3$len,breaks=brks) WR3.age <- subset(WR3, !is.na(age)) WR3.len <- subset(WR3, is.na(age)) head(WR3.len)#> ID len age LCat #> 1 1 37 NA 35 #> 2 2 37 NA 35 #> 3 3 39 NA 35 #> 4 4 37 NA 35 #> 7 7 42 NA 40 #> 8 8 42 NA 40raw <- xtabs(~LCat+age,data=WR3.age) ( WR3.key <- prop.table(raw, margin=1) )#> age #> LCat 4 5 6 7 8 9 #> 35 1.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 40 1.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 45 1.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 50 1.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 55 1.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 60 0.60000000 0.40000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 65 0.00000000 1.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 70 0.00000000 1.00000000 0.00000000 0.00000000 0.00000000 0.00000000 #> 75 0.00000000 0.88888889 0.11111111 0.00000000 0.00000000 0.00000000 #> 80 0.00000000 0.25000000 0.75000000 0.00000000 0.00000000 0.00000000 #> 85 0.00000000 0.00000000 0.90909091 0.09090909 0.00000000 0.00000000 #> 90 0.00000000 0.00000000 0.26315789 0.63157895 0.10526316 0.00000000 #> 95 0.00000000 0.00000000 0.05882353 0.70588235 0.17647059 0.00000000 #> 100 0.00000000 0.00000000 0.00000000 0.48000000 0.24000000 0.24000000 #> 110 0.00000000 0.00000000 0.00000000 0.14285714 0.14285714 0.14285714 #> age #> LCat 10 11 #> 35 0.00000000 0.00000000 #> 40 0.00000000 0.00000000 #> 45 0.00000000 0.00000000 #> 50 0.00000000 0.00000000 #> 55 0.00000000 0.00000000 #> 60 0.00000000 0.00000000 #> 65 0.00000000 0.00000000 #> 70 0.00000000 0.00000000 #> 75 0.00000000 0.00000000 #> 80 0.00000000 0.00000000 #> 85 0.00000000 0.00000000 #> 90 0.00000000 0.00000000 #> 95 0.05882353 0.00000000 #> 100 0.04000000 0.00000000 #> 110 0.42857143 0.14285714WR3.len <- alkIndivAge(WR3.key,age~len,data=WR3.len,breaks=brks)#> Warning: The maximum observed length in the length sample (117) is greater #> than the largest length category in the age-length key (110). #> The last length category will be treated as all-inclusive.head(WR3.len)#> ID len age LCat #> 1 1 37 4 35 #> 2 2 37 4 35 #> 3 3 39 4 35 #> 4 4 37 4 35 #> 7 7 42 4 40 #> 8 8 42 4 40#> age n mean sd min Q1 median Q3 max #> 1 4 987 51.86 5.13 35 48.00 52.0 56.00 64 #> 2 5 395 71.78 5.28 60 68.00 72.0 76.00 84 #> 3 6 269 86.69 4.68 75 83.00 87.0 89.00 98 #> 4 7 451 97.69 5.33 85 93.00 97.0 102.00 114 #> 5 8 141 100.66 5.51 90 97.00 101.0 104.00 113 #> 6 9 79 103.89 3.13 100 101.50 103.0 106.00 113 #> 7 10 41 105.02 7.53 95 98.00 104.0 112.00 119 #> 8 11 6 111.50 1.38 110 110.25 111.5 112.75 113