flr/FLCore

Conversion of data.frame to FLStock does not name first dimension 'age'

Closed this issue · 2 comments

I am trying to develop an option to read in data as a .csv, and convert this "wide" data.frame to an FLStock. My example is for a stock with only a single aggregate age group. When I use as.FLStock the resulting object looks correct except for the fact that the first dimension is named "quant" rather than "age", and thus fails when trying to plot.

library(FLCore)
library(ggplotFL)

df <- structure(list(year = 2003:2019, catch = c(2961, 2767, 3809, 
  5909, 3398, 1379, 3172, 1644, 2318, 2802, 3432, 2701, 1524, 2126, 
  1952, 1997, 5475.44), catch.n = c(177.45, 159.7, 200.5, 314.96, 
  158.55, 60.68, 154.62, 74.43, 98.92, 123.96, 153.96, 98.38, 61.96, 
  92.87, 70.49, 79.2, 219.76), catch.wt = c(16.69, 17.33, 19, 18.76, 
  21.43, 22.72, 20.52, 22.09, 23.43, 22.6, 22.29, 27.46, 24.59, 
  22.89, 27.69, 25.21, 24.92), discards = c(716, 615, 715, 1051, 
  432, 166, 461, 201, 246, 345, 450, 198, 153, 272, 140, 190, 1116.44
  ), discards.n = c(74.9, 66.7, 69.28, 99.34, 39.67, 15.13, 43.74, 
  17.12, 22.32, 33.96, 45.92, 14.67, 15.3, 26.59, 13.02, 16.83, 
  96.63), discards.wt = c(9.56, 9.22, 10.32, 10.58, 10.89, 10.97, 
  10.54, 11.74, 11.02, 10.16, 9.79, 13.59, 9.99, 10.23, 10.28, 
  11.22, 11.55), harvest = c(0.16, 0.12, 0.12, 0.25, 0.19, 0.06, 
  0.23, 0.1, 0.11, 0.16, 0.22, 0.13, 0.12, 0.13, 0.08, 0.08, 0.17
  ), harvest.spwn = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
  NA, NA, NA, NA, NA, NA), landings = c(2245, 2152, 3094, 4858, 
  2966, 1213, 2711, 1443, 2072, 2457, 2982, 2503, 1371, 1854, 1812, 
  1807, 4359), landings.n = c(102.56, 93, 131.21, 215.62, 118.88, 
  45.55, 110.88, 57.31, 76.6, 90, 108.04, 83.71, 46.66, 66.29, 
  57.47, 62.37, 153.82), landings.wt = c(21.89, 23.14, 23.58, 22.53, 
  24.95, 26.63, 24.45, 25.18, 27.05, 27.34, 27.6, 29.93, 29.39, 
  27.97, 29.03, 28.92, 28.34), m = c(NA, NA, NA, NA, NA, NA, NA, 
  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), m.spwn = c(NA, NA, NA, 
  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), mat = c(1, 
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), stock = c(18104.36, 
  23857.94, 31479.52, 23338.68, 18388.75, 22429.49, 13991.33, 17339.36, 
  20573.84, 17134.34, 15737.61, 20728.55, 13896.04, 15955.23, 24977.24, 
  23952.73, 28976.76), stock.n = c(1085, 1377, 1657, 1244, 858, 
  987, 682, 785, 878, 758, 706, 755, 565, 697, 902, 950, 1163), 
  stock.wt = c(16.69, 17.33, 19, 18.76, 21.43, 22.72, 20.52, 
  22.09, 23.43, 22.6, 22.29, 27.46, 24.59, 22.89, 27.69, 25.21, 
  24.92), c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
  NA, NA, NA, NA, NA), c(NA, NA, NA, NA, NA, NA, NA, NA, NA, 
  NA, NA, NA, NA, NA, NA, NA, NA), c(NA, NA, NA, NA, NA, NA, 
  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), c(NA, NA, NA, 
  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), 
  c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
  NA, NA, NA), c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
  NA, NA, NA, NA, NA, NA), stock = c(18104L, 23858L, 31480L, 
  23339L, 18389L, 22429L, 13991L, 17339L, 20574L, 17134L, 15738L, 
  20729L, 13896L, 15955L, 24977L, 23953L, 28977L), SOP = c(18104L, 
  23858L, 31480L, 23339L, 18389L, 22429L, 13991L, 17339L, 20574L, 
  17134L, 15738L, 20729L, 13896L, 15955L, 24977L, 23953L, 28977L
  ), c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
  NA, NA, NA, NA), catch = c(2961L, 2767L, 3809L, 5909L, 3398L, 
  1379L, 3172L, 1644L, 2318L, 2802L, 3432L, 2701L, 1524L, 2126L, 
  1952L, 1997L, 5475L), SOP = c(2961L, 2767L, 3809L, 5909L, 
  3398L, 1379L, 3172L, 1644L, 2318L, 2802L, 3432L, 2701L, 1524L, 
  2126L, 1952L, 1997L, 5475L), c(NA, NA, NA, NA, NA, NA, NA, 
  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), discards = c(716L, 
  615L, 715L, 1051L, 432L, 166L, 461L, 201L, 246L, 345L, 450L, 
  198L, 153L, 272L, 140L, 190L, 1116L), SOP = c(716L, 615L, 
  715L, 1051L, 432L, 166L, 461L, 201L, 246L, 345L, 449L, 199L, 
  153L, 272L, 134L, 189L, 1116L), c(NA, NA, NA, NA, NA, NA, 
  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), landings = c(2245L, 
  2152L, 3094L, 4858L, 2966L, 1213L, 2711L, 1443L, 2072L, 2457L, 
  2982L, 2503L, 1371L, 1854L, 1812L, 1807L, 4359L), SOP = c(2245L, 
  2152L, 3094L, 4858L, 2966L, 1213L, 2711L, 1443L, 2072L, 2461L, 
  2982L, 2505L, 1371L, 1854L, 1668L, 1804L, 4359L)), 
  class = "data.frame", row.names = c(NA, -17L))


stk <- as.FLStock(df)
dimnames(stk)

plot(stk) # fails
# Error in .local(object, ...) : rec(FLStock) only defined for age-based objects 

Is there a way to ensure that the first dimension is called "age". I would then set this to 1, rather than "all" in order to view the numbers in the summary plot.

Thanks for your help.

The data.frame needs to be in the long format, as returned by as.data.frame on an FLStock, with columns year, data and slot. Some of the elements in your structure are repeated (e.g. 'stock'), others are empty, and other do not match a slot name ('SOP').

data(ple4)
head(as.data.frame(ple4[1,], drop=TRUE))

We can assume that df columns 1:18 are the ones you want to use, and then we need to add the quant name to it. It needs correcting for the aggregated slots so they become 'all'.

# RESHAPE to long
mdf <- reshape2::melt(df[, 1:18], id=c("year"),
  variable.name="slot", value.name="data")

# ADD age=1, change to 'all' for aggregated slots
mdf$age <- 1

mdf[mdf$slot %in% c("catch", "landings", "discards", "stock"), "age"] <- "all"

# CONVERT to FLStock
stk <- as.FLStock(mdf)

# SET units so plot does not complain about units(harvest)
units(stk) <- standardUnits(stk)

# PLOT
plot(stk)

'as.FLStock' assumes the dimensions are all specified in the 'data.frame'. You can also have a column called 'units' to pass them for each slot.

Thank you so much! I didn't mean to copy over those other columns, but I see that this wasn't my only problem. Thanks for the quick reply.
-Marc