Introduction

Different oxygen probe systems output oxygen values in many different units of concentration or partial pressure, or even in a proportional unit such as relative percentage of dissolved air or oxygen. For example, it is very common to use water that has been 100% saturated with air through vigorous bubbling, mixing or stirring as the starting value of 100%, with percent saturation recorded as it declines, the assumption being this is the oxygen being removed by the specimen.

The convert_DO() function allows you to convert between any commonly used unit of oxygen concentration, partial pressure, or percent air or oxygen saturation.

Some unit conversions require temperature, salinity, and atmospheric pressure inputs in order to do conversions. The first two of these must be entered if they are required. For the atmospheric pressure input (P), a default value of 1.013 bar (standard pressure at sea level) is applied if not entered. In most locations which have a normal range (outside of extreme weather events) of around 20 millibars, any variability in pressure will have a relatively minor effect on dissolved oxygen, and even less on calculated rates. However, we would encourage users to enter the true value if they know it, or use historical weather data to find out what it was on the day of the experiment.

Concentration units should be formatted as oxygen amount per unit volume or mass in SI units (L or kg) for the denominator. For example, ml/kg or mg/L. A range of different pressure units are also available. See unit_args() for the various units that are accepted.

Example 1 - Saturation conversions

Percent air saturation

The sardine.rd dataset has oxygen values in percent air saturation, and the accompanying help file, help("sardine.rd"), contains the temperature, salinity and atmospheric pressure inputs to allow it to be converted.

sardine.rd
#>        Time Oxygen Temperature
#>       <int>  <num>       <num>
#>    1:     0   95.6      15.192
#>    2:     1   95.6      15.199
#>    3:     2   95.6      15.203
#>    4:     3   95.6      15.193
#>    5:     4   95.6      15.200
#>   ---                         
#> 7509:  7508   90.0      15.106
#> 7510:  7509   90.1      15.106
#> 7511:  7510   90.1      15.106
#> 7512:  7511   90.2      15.109
#> 7513:  7512   90.3      15.099

We will convert it to umol/kg. In convert_DO, the t, S and P inputs must be in °C, ppt (‰), and bar.

conv <- convert_DO(sardine.rd$Oxygen, # data to convert
                   from = "%Air",     # oxygen unit to convert from
                   to = "umol/kg",    # oxygen unit to convert to
                   t = 15,            # in C
                   S = 35,            # in ppt
                   P = 1.013)         # in bar

head(conv)
#> [1] 236.5437 236.5437 236.5437 236.5437 236.5437 236.5437

By default the function outputs a numeric vector of converted values, which can be saved as it’s own object. In this case we will add it to the original data frame.

sardine_new <- cbind(sardine.rd,
                     umol_kg = conv)

sardine_new
#>        Time Oxygen Temperature  umol_kg
#>       <int>  <num>       <num>    <num>
#>    1:     0   95.6      15.192 236.5437
#>    2:     1   95.6      15.199 236.5437
#>    3:     2   95.6      15.203 236.5437
#>    4:     3   95.6      15.193 236.5437
#>    5:     4   95.6      15.200 236.5437
#>   ---                                  
#> 7509:  7508   90.0      15.106 222.6876
#> 7510:  7509   90.1      15.106 222.9350
#> 7511:  7510   90.1      15.106 222.9350
#> 7512:  7511   90.2      15.109 223.1824
#> 7513:  7512   90.3      15.099 223.4299

Alternatively, if simplify = FALSE the output is a list object which can be used with print for a convenient summary output.

conv <- convert_DO(sardine.rd$Oxygen, # data to convert
                   from = "%Air",     # oxygen unit to convert from
                   to = "umol/kg",    # oxygen unit to convert to
                   t = 15,            # in C
                   S = 35,            # in ppt
                   P = 1.013,         # in bar
                   simplify = FALSE)  # output vector of values

print(conv)
#> 
#> # print.convert_DO # --------------------
#> Showing only the first 20 conversions:
#> 
#> Input values:
#>  [1] 95.6 95.6 95.6 95.6 95.6 95.6 95.6 95.5 95.5 95.5 95.6 95.6 95.5 95.5 95.6 95.6 95.6 95.4 95.6 95.6
#> Output values:
#>  [1] 236.5437 236.5437 236.5437 236.5437 236.5437 236.5437 236.5437 236.2963 236.2963 236.2963 236.5437 236.5437 236.2963 236.2963 236.5437 236.5437 236.5437 236.0488 236.5437 236.5437
#> 
#> Input unit:  %Air
#> Output unit: umol/kg
#> -----------------------------------------

Percent oxygen saturation

Note the difference between percent air saturation (%Air), where air saturated water is ~100%, and percent oxygen saturation (%Oxy), where air saturated water is ~20.946% oxygen saturated. In other words, %Oxy = %Air * 0.20946. Some oxygen probe systems output in both units, or tend to use one over the other, so take care not to confuse them.

convert_DO(100, "%Air", "%Oxy",
           t = 15,
           S = 35,            
           P = 1.013)         
#> [1] 20.946

Example 2 - Oxygen pressure units

convert_DO can also convert between units of oxygen partial pressure. We will add a column of the same oxygen values in hectopascals, converting from the umol/kg column we just added.

sardine_new$hPa <- convert_DO(sardine_new$umol_kg,  
                              from = "umol per kg",    
                              to = "hPa",  
                              t = 15,            
                              S = 35,            
                              P = 1.013)     

sardine_new
#>        Time Oxygen Temperature  umol_kg      hPa
#>       <int>  <num>       <num>    <num>    <num>
#>    1:     0   95.6      15.192 236.5437 202.1883
#>    2:     1   95.6      15.199 236.5437 202.1883
#>    3:     2   95.6      15.203 236.5437 202.1883
#>    4:     3   95.6      15.193 236.5437 202.1883
#>    5:     4   95.6      15.200 236.5437 202.1883
#>   ---                                           
#> 7509:  7508   90.0      15.106 222.6876 190.3446
#> 7510:  7509   90.1      15.106 222.9350 190.5561
#> 7511:  7510   90.1      15.106 222.9350 190.5561
#> 7512:  7511   90.2      15.109 223.1824 190.7676
#> 7513:  7512   90.3      15.099 223.4299 190.9791

Note how the from unit is formatted differently but still recognised. Unit conversions in respR use a forgiving, fuzzy algorithm to recognise different variations of unit strings.

Example 3 - Converting single values

For quick conversions, convert_DO also accepts single values. These particular units here do not require temperature, salinity and pressure.

convert_DO(8, 
           "mg/L",
           "mmol/L")
#> [1] 0.2500094

Example 4 - Enter additional inputs in correct units

respR has a convenient helper function to assist with convert_DO (and convert_rate()) where certain inputs such as temperature or atmospheric pressure have to be in specific units.

convert_val() will convert between units of temperature, volume, mass, area, and atmospheric pressure. The utility of using it here is that it will by default convert to the required units for the relevant convert_DO input.

Let’s say we have been reading an old paper and want to convert an oxygen value in ml/L to mg/L, and the temperature and atmospheric pressure values are in Fahrenheit and Torr. For the t and P inputs in convert_DO these must be in °C and bar. We could easily go to an online converter to do this, but convert_val can help do it right within the convert_DO function call.

convert_DO(4.6, 
           from = "ml/L",  
           to = "mg/L",
           t = convert_val(65, from = "F"), # needs to be in C
           S = 30, 
           P = convert_val(775, from = "Torr"), # needs to be in bar
           simplify = FALSE) 
#> 
#> # print.convert_DO # --------------------
#> 
#> Input values:
#> [1] 4.6
#> Output values:
#> [1] 6.282206
#> 
#> Input unit:  mL/L
#> Output unit: mg/L
#> -----------------------------------------

Notice two convenient aspects:

  • We don’t need to tell convert_val what parameter (temperature, pressure, etc.) the value is a measurement of - it is recognised automatically using the from unit.

  • We don’t need to specify a to unit (although it’s possible to). The defaults for these are the required input units, that is °C and bar.

The convert_val() function can also be used for general conversions of temperature, volume, mass, area, and atmospheric pressure in many common units:

convert_val(0, from = "C", to = "K")
#> [1] 273.15
convert_val(1, from = "L", to = "ml")
#> [1] 1000
convert_val(10000, from = "mg", to = "kg")
#> [1] 0.01
convert_val(0.0077, from = "m2", to = "mm2")
#> [1] 7700
convert_val(775, from = "Torr", to = "mbar")
#> [1] 1033.251

See also convert_rate() where convert_val can be used in a similar way with the volume, mass, and area inputs.