Calculating Feed Conversion and Nutrient Use Efficiency

knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)

This short vignette provides coding examples on how to use the functions provided by the aquacultuR package to calculate feed conversion metrics and nutrient use efficiency metrics.

library(aquacultuR)
library(magrittr)
library(dplyr)
library(tidyr)
library(lubridate)
oldopts <- options()
options(digits = 3)

Data

Source and Adjustments

The data we will assess in order to demonstrate the calculation of feed conversion metrics originates from one out of two experiments during with Atlantic salmon (Salmo salar) has been exposed to different levels of dissolved oxygen saturation. The original data was published by @Liland2024a in form of a typical Excel workbook and can be found together with additional information in the dedicated publication. The respective data has been tidied by converting the double-row into single-row column names. More information on tidy data can be found for instance in @Wickham2014a. In addition, proximate and amino acid compositions have been converted from percentages to mass fractions in gram per gram.

Overview

The original dataset provides some information on the feed they used, such as the proximate composition and essential amino acid profile.

feedcomp

We can notice that the dry matter content has not been scaled to 1 (=100%). The other data is thus provided on wet weight basis, which will be important later.

After removing the non-numeric diet column, we will convert the data into long format for improved readability.

feedcomp %>% 
  select(-diet) %>% 
  pivot_longer(
    everything(),
    names_to = "parameter",
    values_to = "value"
  )

The unit of the data is gram per gram. It is highly recommended to use a package such as units to ensure that there are no mistakes occurring with unit conversion.

To calculate the feed conversion and nutrient use efficiency, we need the biomass of the fish stock at the beginning and the end of the growth phase. This data can be found in the samplings dataset. As the data is not in the right shape, we need to make some adjustments. First of all, we will add an additional column (timepoint) as identifier for the fish bodyweight at the beginning and the end. In the next step, we will calculate the arithmetic mean of the weights for each or our timepoints of interest because at the beginning of the growth period the weight was determined in bulk, while fish were weighed individually at the end of the growth period. Lastly, we will convert the data into wide format.

df <- samplings %>%
  mutate(
    timepoint = case_when(
      date == ymd("2023-03-16") ~ "bw_beginning",
      date == ymd("2023-04-14") ~ "bw_end",
      .default = NA
  )) %>%
  group_by(tank, timepoint, sample_type) %>%
  summarise(mean_weight = mean(fish_weight)) %>% 
  select(-sample_type, -starts_with("sd")) %>%
  pivot_wider(
    names_from = timepoint,
    values_from = mean_weight
  ) %>% 
  print()

Additional data we require is that related to the feed intake throughout the growth phase. This can be found in the feed_intake dataset.

head(feed_intake)

To calculate nutrient use efficiency, we also need some data on the bodycomposition at the beginning and the end of the growth period, which can be found in the bodycomp dataset.

head(bodycomp)

Feed Conversion Ratio and Efficiency

To assess feed conversion, we need data on the feed intake throughout the experiment. The feed_intake dataset already comes with the cumulative feed intake pre-calculated, which means we only need to retain the ultimate value. We then join the bodyweight at the beginning and the end of the growth period with the feed intake dataset.

df <- feed_intake %>% 
  filter(date == max(date)) %>% 
  select(tank, cumulative_feed_intake) %>% 
  right_join(df, join_by(tank)) %>% 
  print()

It is eventually possible to calculate the Feed Conversion Ratio (FCR) with the fcr() function and the Feed Conversion Efficiency (FCE) with the fce() function. Note that we account for the dry matter content of the feed, which is not 100%.

feed_conversion <- df %>%
  group_by(tank) %>%
  summarise(
    feed_conversion_ratio = fcr(
      ibw = bw_beginning,
      fbw = bw_end,
      feed = cumulative_feed_intake,
      dm = 0.93
    ),
    feed_conversion_efficiency = fce(
      ibw = bw_beginning,
      fbw = bw_end,
      feed = cumulative_feed_intake,
      dm = 0.93
    )
  ) %>%
  print()

The FCR indicates the quantity of feed required to gain a unit of bodyweight. The FCE, meanwhile, is the inverse of the FCR and thus describes the bodyweight gain per mass unit of feed. Please note that the specific FCR or FCE (economic, biological, etc.) depend on whether the feed quantity is corrected for feed refusal or other kinds of feed losses and whether both the feed quantity and biomass are corrected for their respective dry matter contents.

Nutrient Use Efficiency

Nutrient Efficiency Ratio

To look deeper into the Nutrient Use Efficiency, we are interested in calculating metrics such as the Nutrient Efficiency Ratio (NER). This can be achieved with the ner() function. For this purpose, we need to add the feed composition to the dataset as well. As an example, we will focus on the crude protein and calculate the Protein Efficiency Ratio. Note that the ner() function requires the feed composition data to be provided in gram per gram, which corresponds to possible values within the interval [0,1].

df %>% 
  bind_cols(feedcomp %>% 
              select(dry_matter, crude_protein)) %>% 
  mutate(
    protein_efficiency_ratio = ner(ibw = bw_beginning, 
                                   fbw = bw_end, 
                                   fi = cumulative_feed_intake, 
                                   nut_f = crude_protein, 
                                   dm = dry_matter)
  ) %>% 
  relocate(tank, protein_efficiency_ratio) # change column order

Nutrient Retention

An additional metric we might be interested in is the actual Nutrient Retention (NR), which can be calculated with the nr() function. The Nutrient Retention indicates how much of a specific nutrient provided has actually been retained in the tissue of the fed organism. For this purpose, we require data on the tissue composition.

summary(bodycomp)

In an initial step, we specify the start and end date again.

df2 <- bodycomp %>% 
    mutate(
      timepoint = case_when(
        date == ymd("2023-03-16") ~ "beginning", 
        date == ymd("2023-04-14") ~ "end",
        .default = NA
        )
      )

Now we calculate the initial tissue protein content based on the three samples that were taken to determine the body composition and save the result in a new R object.

initial <- df2 %>% 
  group_by(timepoint) %>% 
  summarise(tissue_protein_start = mean(protein)) %>%
  ungroup() %>% 
  filter(timepoint == "beginning") %>% 
  select(tissue_protein_start) %>% print()

Eventually, we can remove the initial timepoint and add the data together with the feed intake, weight gain, and feed composition data.

nutrient_retention <- df2 %>%
  filter(timepoint != "beginning") %>% 
  rename(tissue_protein = "protein") %>% 
  select(-timepoint) %>% 
  bind_cols(initial) %>% 
  right_join(df, join_by(tank)) %>% 
  bind_cols(feedcomp %>% select(dry_matter, crude_protein))

After joining all necessary data, we can calculate the NR.

nutrient_retention %>% 
  mutate(
    protein_retention = nr(ibw = bw_beginning, 
                           fbw = bw_end, 
                           ibn = tissue_protein_start,
                           fbn = tissue_protein, 
                           fi = cumulative_feed_intake,
                           nut_f = crude_protein
                           )
    ) %>% 
  select(treatment, protein_retention)

Session Info

sessionInfo()
options(oldopts)

References



Try the aquacultuR package in your browser

Any scripts or data that you put into this service are public.

aquacultuR documentation built on Jan. 26, 2026, 5:07 p.m.