Skip to contents

This article walks through how you can apply custom specific gravity conversion factors or adjusted volumes to your input data. Please ensure you have read and understood the Specific gravity article and the workflow of the various underlying functions before applying custom values.

Note that the examples given below show automatic calculation of the majority of the data, and then adjustment of a single row with custom values. This adjustment could be made more automated by building a loop to check if the custom column contains a non-null value, and if so applying the custom calculation. Similarly, the automated calculation could be skipped entirely and a column filled with custom values could instead be used.

These examples follow a very similar process to the examples given in the Workflow article, except the analysis and calculation has been broken into two stages: first, the specific gravity conversion is done, then the NPM scoring and assessment is done. This allows for adjustment of specific gravity values between these two steps.

Where adjusted volume has been provided

As always, we need to load in the data set and the required libraries:

# load required libraries
library(tidyr)
library(dplyr)
library(nutrientprofiler)

# read in the data
example_data <- read.csv("data/example_data.csv")

This dataset has a column called custom_sg_adjusted that is empty except for products where a final adjusted volume based on specific gravity has been provided.

example_data
#>                  name brand product_category product_type food_type
#> 1              lembas    NA               NA         Food          
#> 2     zeno's icecream    NA               NA         Food Ice cream
#> 3         mystic rush    NA               NA        Drink          
#> 4  delta ringer drink    NA               NA        Drink          
#> 5        welter water    NA               NA        Drink          
#> 6       janus's drink    NA               NA         Food          
#> 7   beta ringer drink    NA               NA        Drink          
#> 8   zeta ringer drink    NA               NA        Drink          
#> 9   heavyweight water    NA               NA        Drink          
#> 10       bantam water    NA               NA        Drink          
#>    drink_format             drink_type                     nutrition_info
#> 1                                                                        
#> 2                                                                        
#> 3         Ready Carbonated/juice drink                                   
#> 4      Powdered                            Preparation instructions given
#> 5       Cordial                                               As consumed
#> 6                                                                        
#> 7      Powdered                                               As consumed
#> 8      Powdered                        Preparation instructions not given
#> 9       Cordial                            Preparation instructions given
#> 10      Cordial                        Preparation instructions not given
#>    energy_measurement_kj energy_measurement_kcal sugar_measurement_g
#> 1                    266                      NA                  50
#> 2                     NA                      24                  21
#> 3                     NA                     194                  11
#> 4                    188                      NA                  15
#> 5                     NA                     205                  19
#> 6                     NA                      24                  21
#> 7                    188                      NA                  15
#> 8                    188                      NA                  15
#> 9                     NA                     205                  19
#> 10                    NA                     205                  19
#>    satfat_measurement_g salt_measurement_g sodium_measurement_mg
#> 1                     3                 NA                   0.6
#> 2                    11               0.08                    NA
#> 3                     0                 NA                 100.0
#> 4                     0                 NA                 100.0
#> 5                     0               0.10                    NA
#> 6                    11               0.08                    NA
#> 7                     0                 NA                 100.0
#> 8                     0                 NA                 100.0
#> 9                     0               0.10                    NA
#> 10                    0               0.10                    NA
#>    fibre_measurement_nsp fibre_measurement_aoac protein_measurement_g
#> 1                      3                     NA                   7.0
#> 2                     NA                    0.7                   3.5
#> 3                     NA                    0.0                   0.0
#> 4                     NA                    0.0                   0.5
#> 5                     NA                    0.0                   0.1
#> 6                     NA                    0.7                   3.5
#> 7                     NA                    0.0                   0.5
#> 8                     NA                    0.0                   0.5
#> 9                     NA                    0.0                   0.1
#> 10                    NA                    0.0                   0.1
#>    fvn_measurement_percent weight_g volume_ml volume_water_ml
#> 1                        0      100        NA              NA
#> 2                        0       NA       100              NA
#> 3                        0       NA       100              NA
#> 4                        3       25        NA             100
#> 5                        6       NA       100              NA
#> 6                        0       NA       100              NA
#> 7                        3       NA        50              NA
#> 8                        3       25        NA              NA
#> 9                        6       NA        20             100
#> 10                       6       NA       100              NA
#>    custom_sg_adjusted
#> 1                  NA
#> 2                  NA
#> 3                  NA
#> 4                  NA
#> 5                  NA
#> 6                  NA
#> 7                  NA
#> 8                  NA
#> 9                 125
#> 10                 NA

Now, we calculate specific gravities as usual, initially ignoring the custom values, before then modifying the output to include our custom values:

example_data_sg_calc <- example_data %>% 
  rowwise() %>% 
  mutate( sg = SGConverter(pick(everything()))) %>% 
  select(everything(), sg)

print("Before setting custom values:")
#> [1] "Before setting custom values:"
print(example_data_sg_calc$sg)
#>  [1] 100.00 130.00 104.00 128.75 103.00 100.00  51.50  25.00 123.60 109.00

example_data_sg_calc$sg[[9]] <- example_data_sg_calc$custom_sg_adjusted[[9]]

print("After setting custom values:")
#> [1] "After setting custom values:"
print(example_data_sg_calc$sg)
#>  [1] 100.00 130.00 104.00 128.75 103.00 100.00  51.50  25.00 125.00 109.00

We can then continue with our analysis using the newly updated specific gravity values:

example_data_results <- example_data_sg_calc %>% 
  rowwise() %>% 
  mutate(test = NPMScore(pick(everything()), sg_adjusted_label="sg")) %>% 
  unnest(test) %>% 
  rowwise() %>%
  mutate(assess = NPMAssess(pick(everything()))) %>%
  unnest(assess) %>%
  select(everything(), energy_score, sugar_score, salt_score, fvn_score,
  protein_score, satfat_score, fibre_score, NPM_score, NPM_assessment)

Our results table looks much the same as for previous examples, with the addition of the custom_sg_adjusted column to record where manual modification has occurred.

names(example_data_results)
#>  [1] "name"                    "brand"                  
#>  [3] "product_category"        "product_type"           
#>  [5] "food_type"               "drink_format"           
#>  [7] "drink_type"              "nutrition_info"         
#>  [9] "energy_measurement_kj"   "energy_measurement_kcal"
#> [11] "sugar_measurement_g"     "satfat_measurement_g"   
#> [13] "salt_measurement_g"      "sodium_measurement_mg"  
#> [15] "fibre_measurement_nsp"   "fibre_measurement_aoac" 
#> [17] "protein_measurement_g"   "fvn_measurement_percent"
#> [19] "weight_g"                "volume_ml"              
#> [21] "volume_water_ml"         "custom_sg_adjusted"     
#> [23] "sg"                      "energy_score"           
#> [25] "sugar_score"             "satfat_score"           
#> [27] "protein_score"           "salt_score"             
#> [29] "fvn_score"               "fibre_score"            
#> [31] "A_score"                 "C_score"                
#> [33] "NPM_score"               "NPM_assessment"

example_data_results[c("name", "sg", "custom_sg_adjusted", "NPM_score", "NPM_assessment")]
#> # A tibble: 10 × 5
#>    name                  sg custom_sg_adjusted NPM_score NPM_assessment
#>    <chr>              <dbl>              <dbl>     <dbl> <chr>         
#>  1 lembas             100                   NA         8 FAIL          
#>  2 zeno's icecream    130                   NA        11 FAIL          
#>  3 mystic rush        104                   NA         5 FAIL          
#>  4 delta ringer drink 129.                  NA         2 FAIL          
#>  5 welter water       103                   NA         6 FAIL          
#>  6 janus's drink      100                   NA        14 FAIL          
#>  7 beta ringer drink   51.5                 NA         9 FAIL          
#>  8 zeta ringer drink   25                   NA        16 FAIL          
#>  9 heavyweight water  125                  125         5 FAIL          
#> 10 bantam water       109                   NA         5 FAIL

Where a custom conversion factor has been provided

Again, we load the required libraries and data:

# load required libraries
library(tidyr)
library(dplyr)
library(nutrientprofiler)

# read in the data
example_data_2 <- read.csv("data/example_data_2.csv")

This dataset has a column called custom_sg_conversion that is empty except for products where a custom specific gravity conversion factor has been provided.

example_data_2
#>                  name brand product_category product_type food_type
#> 1              lembas    NA               NA         Food          
#> 2     zeno's icecream    NA               NA         Food Ice cream
#> 3         mystic rush    NA               NA        Drink          
#> 4  delta ringer drink    NA               NA        Drink          
#> 5        welter water    NA               NA        Drink          
#> 6       janus's drink    NA               NA         Food          
#> 7   beta ringer drink    NA               NA        Drink          
#> 8   zeta ringer drink    NA               NA        Drink          
#> 9   heavyweight water    NA               NA        Drink          
#> 10       bantam water    NA               NA        Drink          
#>    drink_format             drink_type                     nutrition_info
#> 1                                                                        
#> 2                                                                        
#> 3         Ready Carbonated/juice drink                                   
#> 4      Powdered                            Preparation instructions given
#> 5       Cordial                                               As consumed
#> 6                                                                        
#> 7      Powdered                                               As consumed
#> 8      Powdered                        Preparation instructions not given
#> 9       Cordial                            Preparation instructions given
#> 10      Cordial                        Preparation instructions not given
#>    energy_measurement_kj energy_measurement_kcal sugar_measurement_g
#> 1                    266                      NA                  50
#> 2                     NA                      24                  21
#> 3                     NA                     194                  11
#> 4                    188                      NA                  15
#> 5                     NA                     205                  19
#> 6                     NA                      24                  21
#> 7                    188                      NA                  15
#> 8                    188                      NA                  15
#> 9                     NA                     205                  19
#> 10                    NA                     205                  19
#>    satfat_measurement_g salt_measurement_g sodium_measurement_mg
#> 1                     3                 NA                   0.6
#> 2                    11               0.08                    NA
#> 3                     0                 NA                 100.0
#> 4                     0                 NA                 100.0
#> 5                     0               0.10                    NA
#> 6                    11               0.08                    NA
#> 7                     0                 NA                 100.0
#> 8                     0                 NA                 100.0
#> 9                     0               0.10                    NA
#> 10                    0               0.10                    NA
#>    fibre_measurement_nsp fibre_measurement_aoac protein_measurement_g
#> 1                      3                     NA                   7.0
#> 2                     NA                    0.7                   3.5
#> 3                     NA                    0.0                   0.0
#> 4                     NA                    0.0                   0.5
#> 5                     NA                    0.0                   0.1
#> 6                     NA                    0.7                   3.5
#> 7                     NA                    0.0                   0.5
#> 8                     NA                    0.0                   0.5
#> 9                     NA                    0.0                   0.1
#> 10                    NA                    0.0                   0.1
#>    fvn_measurement_percent weight_g volume_ml volume_water_ml
#> 1                        0      100        NA              NA
#> 2                        0       NA       100              NA
#> 3                        0       NA       100              NA
#> 4                        3       25        NA             100
#> 5                        6       NA       100              NA
#> 6                        0       NA       100              NA
#> 7                        3       NA        50              NA
#> 8                        3       25        NA              NA
#> 9                        6       NA        20             100
#> 10                       6       NA       100              NA
#>    custom_sg_conversion
#> 1                    NA
#> 2                    NA
#> 3                    NA
#> 4                    NA
#> 5                    NA
#> 6                    NA
#> 7                    NA
#> 8                    NA
#> 9                  0.83
#> 10                   NA

Now, we calculate specific gravities as usual, initially ignoring the custom values.

example_data_sg_calc_2 <- example_data_2 %>% 
  rowwise() %>% 
  mutate( sg = SGConverter(pick(everything()))) %>% 
  select(everything(), sg)

We can use the function generic_specific_gravity() to calculate the adjusted volumes. The value we want to modify is a cordial, and the nutrition information provided assumes the product has been prepared as instructed (nutrition_info == "Preparation instructions given"); This means we need to calculate the adjusted specific gravity weight by adding the volume (ml) and the volume of water (ml) provided and using these as parameters along with our custom conversion factor in the generic_specific_gravity() function.

print("Before setting custom values:")
#> [1] "Before setting custom values:"
print(example_data_sg_calc_2$sg)
#>  [1] 100.00 130.00 104.00 128.75 103.00 100.00  51.50  25.00 123.60 109.00

example_data_sg_calc_2[9,]
#> # A tibble: 1 × 23
#> # Rowwise: 
#>   name     brand product_category product_type food_type drink_format drink_type
#>   <chr>    <lgl> <lgl>            <chr>        <chr>     <chr>        <chr>     
#> 1 heavywe… NA    NA               Drink        ""        Cordial      ""        
#> # ℹ 16 more variables: nutrition_info <chr>, energy_measurement_kj <int>,
#> #   energy_measurement_kcal <int>, sugar_measurement_g <int>,
#> #   satfat_measurement_g <int>, salt_measurement_g <dbl>,
#> #   sodium_measurement_mg <dbl>, fibre_measurement_nsp <int>,
#> #   fibre_measurement_aoac <dbl>, protein_measurement_g <dbl>,
#> #   fvn_measurement_percent <int>, weight_g <int>, volume_ml <int>,
#> #   volume_water_ml <int>, custom_sg_conversion <dbl>, sg <dbl>
# example_data_sg_calc$sg[[9]] <- example_data_sg_calc$custom_sg_adjusted[[9]]

row <- example_data_sg_calc_2[9,]

example_data_sg_calc_2$sg[[9]] <- generic_specific_gravity((as.numeric(row[["volume_water_ml"]]) + as.numeric(row[["volume_ml"]])),
            row[["custom_sg_conversion"]])

print("After setting custom values:")
#> [1] "After setting custom values:"
print(example_data_sg_calc_2$sg)
#>  [1] 100.00 130.00 104.00 128.75 103.00 100.00  51.50  25.00  99.60 109.00

We can then continue with our analysis using the newly updated specific gravity values:

example_data_results_2 <- example_data_sg_calc_2 %>% 
  rowwise() %>% 
  mutate(test = NPMScore(pick(everything()), sg_adjusted_label="sg")) %>% 
  unnest(test) %>% 
  rowwise() %>%
  mutate(assess = NPMAssess(pick(everything()))) %>%
  unnest(assess) %>%
  select(everything(), energy_score, sugar_score, salt_score, fvn_score,
  protein_score, satfat_score, fibre_score, NPM_score, NPM_assessment)

Our results table looks much the same as for previous examples, with the addition of the custom_sg_conversion column to record where manual modification has occurred.

names(example_data_results_2)
#>  [1] "name"                    "brand"                  
#>  [3] "product_category"        "product_type"           
#>  [5] "food_type"               "drink_format"           
#>  [7] "drink_type"              "nutrition_info"         
#>  [9] "energy_measurement_kj"   "energy_measurement_kcal"
#> [11] "sugar_measurement_g"     "satfat_measurement_g"   
#> [13] "salt_measurement_g"      "sodium_measurement_mg"  
#> [15] "fibre_measurement_nsp"   "fibre_measurement_aoac" 
#> [17] "protein_measurement_g"   "fvn_measurement_percent"
#> [19] "weight_g"                "volume_ml"              
#> [21] "volume_water_ml"         "custom_sg_conversion"   
#> [23] "sg"                      "energy_score"           
#> [25] "sugar_score"             "satfat_score"           
#> [27] "protein_score"           "salt_score"             
#> [29] "fvn_score"               "fibre_score"            
#> [31] "A_score"                 "C_score"                
#> [33] "NPM_score"               "NPM_assessment"

example_data_results_2[c("name", "sg", "custom_sg_conversion", "NPM_score", "NPM_assessment")]
#> # A tibble: 10 × 5
#>    name                  sg custom_sg_conversion NPM_score NPM_assessment
#>    <chr>              <dbl>                <dbl>     <dbl> <chr>         
#>  1 lembas             100                  NA            8 FAIL          
#>  2 zeno's icecream    130                  NA           11 FAIL          
#>  3 mystic rush        104                  NA            5 FAIL          
#>  4 delta ringer drink 129.                 NA            2 FAIL          
#>  5 welter water       103                  NA            6 FAIL          
#>  6 janus's drink      100                  NA           14 FAIL          
#>  7 beta ringer drink   51.5                NA            9 FAIL          
#>  8 zeta ringer drink   25                  NA           16 FAIL          
#>  9 heavyweight water   99.6                 0.83         6 FAIL          
#> 10 bantam water       109                  NA            5 FAIL