Sample results are measurement results (i.e., numeric) associated with an ex-situ procedure performed on a physical specimen collected at a site in the field. This is represented in the datbase as:

Results are associated with the “feature action” of analyzing the sample. Multiple variables can be associated with the same procedure in the lab, such as multiple peak values from the GC. Each variable is described as a separate result with its own units and missing data value.

See the bottom of this page for a diagram.

Prepare data

Dataset to upload must have columns for:

Timestamp will be used for the time the sample was collected. If you want to specify the time the sample was analyzed in the lab, use a column named “Timestamp_analysis” (otherwise this defaults to the current time). Make sure the time is formatted as YYYY-MM-DD HH:MM:SS. If you need to specify a time zone other than the current one, use a POSIXct data type with the correct time zone specified. To convert from any other (non-ambiguous) date format, you can use the strptime() functon.

Example input data set:

soil_ph <- data.frame(
  Timestamp = "2018-02-05 23:59:59",
  Site = "QB SC-A",
  Sample = "CEM 2",
  pH = 4.5,
  stringsAsFactors = FALSE
)
Timestamp Site Sample pH
2018-02-05 23:59:59 QB SC-A CEM 2 4.5

Click here to see a list of the site codes currently in the database.

Variables and units

Metadata about variables needs to be stored in a list with the format:

list("Variable1 Name" = list(column = "ColumnName", units = "Units Name"),
     "Variable2 Name" = list(column = "ColumnName", units = "Units Name"))
vars_list = list("pH" = list(column = "pH", units = "pH"))

If the column name is the exact name of the variable from the controlled vocabulary (i.e. with spaces and correct capitalization), column does not need to be specified. If there are columns in your data that have data quality codes or censor codes, those should be specified here as qualitycodecol and censorcodecol respectively. You can also specify a variabletypecv, variabledefinition and nodatavalue for variables that haven’t been entered to the database before.

Variable names and units names need to be from the controlled vocabularies. To see these options, use the get_cv_terms() function (requires having the rodm2 package loaded, see below).

get_cv_terms("variablename")
get_cv_terms("units")

Connect

Load the rodm2 package, and connect to the database. Or for testing or other purposes you can make a new sqlite database. In this example the database connection object is db.

devtools::install_github("khondula/rodm2")
library(rodm2)
db <- create_sqlite(connect = TRUE)

Insert data

Use the db_insert_results_samples() function from the rodm2 package. You must supply the database connection, data frame, variables list, code names for the methods used in the field and lab, and the sampled medium from the controlled vocabulary (e.g. Air, Soil, etc.). Sampled medium choices can be viewed using get_cv_terms("medium").

db_insert_results_samples(db = db,
                          datavalues = soil_ph,
                          field_method = "test field method",
                          lab_method = "test lab method",
                          variables = vars_list,
                          sampledmedium = "Soil")
Raw data has been inserted into the processinglevel table.
Sample  CEM 2 and associated data have been entered.
[[1]]
NULL

Arguments with defaults

Use these arguments if needed to change defaults:

  • site_code_col = “Site”
  • sample_code_col = “Sample”
  • processinglevel = “Raw data”
  • aggregationstatistic = “Unknown”
  • time_aggregation_interval = list(1, “Minute”)

Optional arguments

  • field_actionby: specify who led the field action
  • lab_actionby: specify who led the lab action
  • field_equipment_name: specify the name of the equipment used in the field
  • lab_equipment_name: specify the name of equipment used in the lab
  • zlocation: specify a vertical offset from the site location to associate with the results
  • zlocationunits: specify the units of the vertical offset

Note: field_actionby & lab_actionby must be people who are already in the database (can be added using the db_describe_person() function). Similarly, field_equipment_name & lab_equipment_name must be equipment already in the database (can be added using the db_describe_equipment() function).

Query results

will need to make this a little more complex to get site collected from and lab method, but for now this proves that the data was inserted.

SELECT datavalue, res.resultid, var.variablenamecv, units.unitsname, valuedatetime, sf.samplingfeaturecode, meth.methodcode
FROM measurementresultvalues mrv
INNER JOIN results res ON mrv.resultid = res.resultid
INNER JOIN variables var ON res.variableid = var.variableid
INNER JOIN featureactions fa ON res.featureactionid = fa.featureactionid
INNER JOIN samplingfeatures sf ON sf.samplingfeatureid = fa.samplingfeatureid
INNER JOIN actions acts ON acts.actionid = fa.actionid
INNER JOIN units units ON units.unitsid = res.unitsid
INNER JOIN methods meth ON meth.methodid = acts.methodid
DataValue ResultID VariableNameCV UnitsName ValueDateTime SamplingFeatureCode MethodCode
4.5 1 pH pH 2018-02-05 23:59:59 CEM 1 test lab method

Under the hood

This diagram shows the connections between the tables that are potentially updated when adding samples. Gray boxes are reference tables, blue boxes describe the actual data values, and yellow tables describe the sample collection and analysis.

LS0tCnRpdGxlOiAiSW5zZXJ0IHNhbXBsZSByZXN1bHRzIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgoKU2FtcGxlIHJlc3VsdHMgYXJlIG1lYXN1cmVtZW50IHJlc3VsdHMgKGkuZS4sIG51bWVyaWMpIGFzc29jaWF0ZWQgd2l0aCBhbiBleC1zaXR1IHByb2NlZHVyZSBwZXJmb3JtZWQgb24gYSBwaHlzaWNhbCBzcGVjaW1lbiBjb2xsZWN0ZWQgYXQgYSBzaXRlIGluIHRoZSBmaWVsZC4gVGhpcyBpcyByZXByZXNlbnRlZCBpbiB0aGUgZGF0YmFzZSBhczoKCiogYSAqKnNhbXBsZSBjb2xsZWN0aW9uIGFjdGlvbioqLCBzcGVjaWZ5aW5nIGhvdyAobWV0aG9kKSBhbmQgd2hlbiAoVGltZXN0YW1wKSB0aGUgc2FtcGxlIChzYW1wbGUgY29kZSkgd2FzIHRha2VuLiBGb3IgZXhhbXBsZSwgIlNhbXBsZSAwMDEgY29sbGVjdGVkIG9uIDIwMTgtMDItMDUgMTM6MDA6MDAgdXNpbmcgdGhlIDEgaW5jaCAzMCBjbSBzb2lsIGNvcmUgbWV0aG9kLiIKKiBXaGVyZSB0aGUgc2FtcGxlIHdhcyBjb2xsZWN0ZWQgaXMgcmVjb3JkZWQgdXNpbmcgdGhlICJ3YXMgY29sbGVjdGVkIGF0IiByZWxhdGlvbnNoaXAgdHlwZTogIlNhbXBsZSAwMDEgd2FzIGNvbGxlY3RlZCBhdCBTaXRlIEEiLgoqIEEgKipzYW1wbGUgYW5hbHlzaXMgYWN0aW9uKiosIHNwZWNpZnlpbmcgaG93IGFuZCB3aGVuIHRoZSByZXN1bHRzIHdlcmUgcHJvZHVjZWQsIGkuZS4gaG93IGFuZCB3aGVuIHRoZSBzYW1wbGUgd2FzIGFuYWx5emVkIGluIHRoZSBsYWIuIAoKUmVzdWx0cyBhcmUgYXNzb2NpYXRlZCB3aXRoIHRoZSAiZmVhdHVyZSBhY3Rpb24iIG9mIGFuYWx5emluZyB0aGUgc2FtcGxlLiBNdWx0aXBsZSB2YXJpYWJsZXMgY2FuIGJlIGFzc29jaWF0ZWQgd2l0aCB0aGUgc2FtZSBwcm9jZWR1cmUgaW4gdGhlIGxhYiwgc3VjaCBhcyBtdWx0aXBsZSBwZWFrIHZhbHVlcyBmcm9tIHRoZSBHQy4gRWFjaCB2YXJpYWJsZSBpcyBkZXNjcmliZWQgYXMgYSBzZXBhcmF0ZSByZXN1bHQgd2l0aCBpdHMgb3duIHVuaXRzIGFuZCBtaXNzaW5nIGRhdGEgdmFsdWUuIAoKU2VlIHRoZSBib3R0b20gb2YgdGhpcyBwYWdlIGZvciBhIGRpYWdyYW0uCgojIFByZXBhcmUgZGF0YQoKRGF0YXNldCB0byB1cGxvYWQgbXVzdCBoYXZlIGNvbHVtbnMgZm9yOgoKKiBUaW1lc3RhbXAgZm9ybWF0dGVkIGFzOiBZWVlZLU1NLUREIEhIOk1NOlNTCiogU2l0ZQoqIFNhbXBsZSBJRAoqIE9uZSBjb2x1bW4gZm9yIGVhY2ggdmFyaWFibGUuIAoKVGltZXN0YW1wIHdpbGwgYmUgdXNlZCBmb3IgdGhlIHRpbWUgdGhlIHNhbXBsZSB3YXMgY29sbGVjdGVkLiBJZiB5b3Ugd2FudCB0byBzcGVjaWZ5IHRoZSB0aW1lIHRoZSBzYW1wbGUgd2FzIGFuYWx5emVkIGluIHRoZSBsYWIsIHVzZSBhIGNvbHVtbiBuYW1lZCAiVGltZXN0YW1wX2FuYWx5c2lzIiAob3RoZXJ3aXNlIHRoaXMgZGVmYXVsdHMgdG8gdGhlIGN1cnJlbnQgdGltZSkuIE1ha2Ugc3VyZSB0aGUgdGltZSBpcyBmb3JtYXR0ZWQgYXMgWVlZWS1NTS1ERCBISDpNTTpTUy4gSWYgeW91IG5lZWQgdG8gc3BlY2lmeSBhIHRpbWUgem9uZSBvdGhlciB0aGFuIHRoZSBjdXJyZW50IG9uZSwgdXNlIGEgUE9TSVhjdCBkYXRhIHR5cGUgd2l0aCB0aGUgY29ycmVjdCB0aW1lIHpvbmUgc3BlY2lmaWVkLiBUbyBjb252ZXJ0IGZyb20gYW55IG90aGVyIChub24tYW1iaWd1b3VzKSBkYXRlIGZvcm1hdCwgeW91IGNhbiB1c2UgdGhlIGBzdHJwdGltZSgpYCBmdW5jdG9uLiAKCkV4YW1wbGUgaW5wdXQgZGF0YSBzZXQ6CgpgYGB7cn0Kc29pbF9waCA8LSBkYXRhLmZyYW1lKAogIFRpbWVzdGFtcCA9ICIyMDE4LTAyLTA1IDIzOjU5OjU5IiwKICBTaXRlID0gIlFCIFNDLUEiLAogIFNhbXBsZSA9ICJDRU0gMiIsCiAgcEggPSA0LjUsCiAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFCikKYGBgCgpgYGB7ciBlY2hvPUZBTFNFLCByZXN1bHRzPSdhc2lzJ30Ka25pdHI6OmthYmxlKHNvaWxfcGgpCmBgYApDbGljayBbaGVyZV0oaHR0cHM6Ly9wYWxtZXJsYWIudW1kLmVkdS9jaG9wdGFuay1kYi9jdXJyZW50LXNpdGVzLm5iLmh0bWwpIHRvIHNlZSBhIGxpc3Qgb2YgdGhlIHNpdGUgY29kZXMgY3VycmVudGx5IGluIHRoZSBkYXRhYmFzZS4gCgojIyBWYXJpYWJsZXMgYW5kIHVuaXRzIAoKTWV0YWRhdGEgYWJvdXQgdmFyaWFibGVzIG5lZWRzIHRvIGJlIHN0b3JlZCBpbiBhIGxpc3Qgd2l0aCB0aGUgZm9ybWF0OgoKYGBgCmxpc3QoIlZhcmlhYmxlMSBOYW1lIiA9IGxpc3QoY29sdW1uID0gIkNvbHVtbk5hbWUiLCB1bml0cyA9ICJVbml0cyBOYW1lIiksCiAgICAgIlZhcmlhYmxlMiBOYW1lIiA9IGxpc3QoY29sdW1uID0gIkNvbHVtbk5hbWUiLCB1bml0cyA9ICJVbml0cyBOYW1lIikpCmBgYAoKYGBge3J9CnZhcnNfbGlzdCA9IGxpc3QoInBIIiA9IGxpc3QoY29sdW1uID0gInBIIiwgdW5pdHMgPSAicEgiKSkKYGBgCgpJZiB0aGUgY29sdW1uIG5hbWUgaXMgdGhlIGV4YWN0IG5hbWUgb2YgdGhlIHZhcmlhYmxlIGZyb20gdGhlIGNvbnRyb2xsZWQgdm9jYWJ1bGFyeSAoaS5lLiB3aXRoIHNwYWNlcyBhbmQgY29ycmVjdCBjYXBpdGFsaXphdGlvbiksIGNvbHVtbiBkb2VzIG5vdCBuZWVkIHRvIGJlIHNwZWNpZmllZC4gSWYgdGhlcmUgYXJlIGNvbHVtbnMgaW4geW91ciBkYXRhIHRoYXQgaGF2ZSBkYXRhIHF1YWxpdHkgY29kZXMgb3IgY2Vuc29yIGNvZGVzLCB0aG9zZSBzaG91bGQgYmUgc3BlY2lmaWVkIGhlcmUgYXMgIHF1YWxpdHljb2RlY29sIGFuZCBjZW5zb3Jjb2RlY29sIHJlc3BlY3RpdmVseS4gWW91IGNhbiBhbHNvIHNwZWNpZnkgYSB2YXJpYWJsZXR5cGVjdiwgdmFyaWFibGVkZWZpbml0aW9uIGFuZCBub2RhdGF2YWx1ZSBmb3IgdmFyaWFibGVzIHRoYXQgaGF2ZW7igJl0IGJlZW4gZW50ZXJlZCB0byB0aGUgZGF0YWJhc2UgYmVmb3JlLgoKVmFyaWFibGUgbmFtZXMgYW5kIHVuaXRzIG5hbWVzIG5lZWQgdG8gYmUgZnJvbSB0aGUgY29udHJvbGxlZCB2b2NhYnVsYXJpZXMuIFRvIHNlZSB0aGVzZSBvcHRpb25zLCB1c2UgdGhlIGBnZXRfY3ZfdGVybXMoKWAgZnVuY3Rpb24gKHJlcXVpcmVzIGhhdmluZyB0aGUgYHJvZG0yYCBwYWNrYWdlIGxvYWRlZCwgc2VlIGJlbG93KS4KCmBgYHtyLCBldmFsID0gRkFMU0V9CmdldF9jdl90ZXJtcygidmFyaWFibGVuYW1lIikKZ2V0X2N2X3Rlcm1zKCJ1bml0cyIpCmBgYAoKIyMgQ29ubmVjdCAKCkxvYWQgdGhlIGByb2RtMmAgcGFja2FnZSwgYW5kIGNvbm5lY3QgdG8gdGhlIGRhdGFiYXNlLiBPciBmb3IgdGVzdGluZyBvciBvdGhlciBwdXJwb3NlcyB5b3UgY2FuIG1ha2UgYSBuZXcgc3FsaXRlIGRhdGFiYXNlLiBJbiB0aGlzIGV4YW1wbGUgdGhlIGRhdGFiYXNlIGNvbm5lY3Rpb24gb2JqZWN0IGlzIGBkYmAuCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgY29tbWVudD1GQUxTRSwgd2FybmluZz1GQUxTRX0KZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJraG9uZHVsYS9yb2RtMiIpCmxpYnJhcnkocm9kbTIpCmRiIDwtIGNyZWF0ZV9zcWxpdGUoY29ubmVjdCA9IFRSVUUpCmBgYAoKCiMjIEluc2VydCBkYXRhCgpVc2UgdGhlIGBkYl9pbnNlcnRfcmVzdWx0c19zYW1wbGVzKClgIGZ1bmN0aW9uIGZyb20gdGhlIHJvZG0yIHBhY2thZ2UuIFlvdSBtdXN0IHN1cHBseSB0aGUgZGF0YWJhc2UgY29ubmVjdGlvbiwgZGF0YSBmcmFtZSwgdmFyaWFibGVzIGxpc3QsIGNvZGUgbmFtZXMgZm9yIHRoZSBtZXRob2RzIHVzZWQgaW4gdGhlIGZpZWxkIGFuZCBsYWIsIGFuZCB0aGUgc2FtcGxlZCBtZWRpdW0gZnJvbSB0aGUgY29udHJvbGxlZCB2b2NhYnVsYXJ5IChlLmcuIEFpciwgU29pbCwgZXRjLikuIFNhbXBsZWQgbWVkaXVtIGNob2ljZXMgY2FuIGJlIHZpZXdlZCB1c2luZyBgZ2V0X2N2X3Rlcm1zKCJtZWRpdW0iKWAuCgpgYGB7cn0KZGJfaW5zZXJ0X3Jlc3VsdHNfc2FtcGxlcyhkYiA9IGRiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGF2YWx1ZXMgPSBzb2lsX3BoLAogICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX21ldGhvZCA9ICJ0ZXN0IGZpZWxkIG1ldGhvZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiX21ldGhvZCA9ICJ0ZXN0IGxhYiBtZXRob2QiLAogICAgICAgICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlcyA9IHZhcnNfbGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICBzYW1wbGVkbWVkaXVtID0gIlNvaWwiKQpgYGAKCgoqKkFyZ3VtZW50cyB3aXRoIGRlZmF1bHRzKioKClVzZSB0aGVzZSBhcmd1bWVudHMgaWYgbmVlZGVkIHRvIGNoYW5nZSBkZWZhdWx0czoKCiogc2l0ZV9jb2RlX2NvbCA9ICJTaXRlIgoqIHNhbXBsZV9jb2RlX2NvbCA9ICJTYW1wbGUiCiogcHJvY2Vzc2luZ2xldmVsID0gIlJhdyBkYXRhIgoqIGFnZ3JlZ2F0aW9uc3RhdGlzdGljID0gIlVua25vd24iCiogdGltZV9hZ2dyZWdhdGlvbl9pbnRlcnZhbCA9IGxpc3QoMSwgIk1pbnV0ZSIpCgoqKk9wdGlvbmFsIGFyZ3VtZW50cyoqCgoqIGZpZWxkX2FjdGlvbmJ5OiBzcGVjaWZ5IHdobyBsZWQgdGhlIGZpZWxkIGFjdGlvbgoqIGxhYl9hY3Rpb25ieTogc3BlY2lmeSB3aG8gbGVkIHRoZSBsYWIgYWN0aW9uCiogZmllbGRfZXF1aXBtZW50X25hbWU6IHNwZWNpZnkgdGhlIG5hbWUgb2YgdGhlIGVxdWlwbWVudCB1c2VkIGluIHRoZSBmaWVsZAoqIGxhYl9lcXVpcG1lbnRfbmFtZTogc3BlY2lmeSB0aGUgbmFtZSBvZiBlcXVpcG1lbnQgdXNlZCBpbiB0aGUgbGFiCiogemxvY2F0aW9uOiBzcGVjaWZ5IGEgdmVydGljYWwgb2Zmc2V0IGZyb20gdGhlIHNpdGUgbG9jYXRpb24gdG8gYXNzb2NpYXRlIHdpdGggdGhlIHJlc3VsdHMKKiB6bG9jYXRpb251bml0czogc3BlY2lmeSB0aGUgdW5pdHMgb2YgdGhlIHZlcnRpY2FsIG9mZnNldAoKPiBOb3RlOiBmaWVsZF9hY3Rpb25ieSAmIGxhYl9hY3Rpb25ieSBtdXN0IGJlIHBlb3BsZSB3aG8gYXJlIGFscmVhZHkgaW4gdGhlIGRhdGFiYXNlIChjYW4gYmUgYWRkZWQgdXNpbmcgdGhlIGBkYl9kZXNjcmliZV9wZXJzb24oKWAgZnVuY3Rpb24pLgo+IFNpbWlsYXJseSwgZmllbGRfZXF1aXBtZW50X25hbWUgJiBsYWJfZXF1aXBtZW50X25hbWUgbXVzdCBiZSBlcXVpcG1lbnQgYWxyZWFkeSBpbiB0aGUgZGF0YWJhc2UgKGNhbiBiZSBhZGRlZCB1c2luZyB0aGUgYGRiX2Rlc2NyaWJlX2VxdWlwbWVudCgpYCBmdW5jdGlvbikuCgojIyBRdWVyeSByZXN1bHRzCgp3aWxsIG5lZWQgdG8gbWFrZSB0aGlzIGEgbGl0dGxlIG1vcmUgY29tcGxleCB0byBnZXQgc2l0ZSBjb2xsZWN0ZWQgZnJvbSBhbmQgbGFiIG1ldGhvZCwgYnV0IGZvciBub3cgdGhpcyBwcm92ZXMgdGhhdCB0aGUgZGF0YSB3YXMgaW5zZXJ0ZWQuIAoKYGBge3NxbCwgY29ubmVjdGlvbj1kYiwgb3V0cHV0LnZhciA9ICJkYm91dCJ9ClNFTEVDVCBkYXRhdmFsdWUsIHJlcy5yZXN1bHRpZCwgdmFyLnZhcmlhYmxlbmFtZWN2LCB1bml0cy51bml0c25hbWUsIHZhbHVlZGF0ZXRpbWUsIHNmLnNhbXBsaW5nZmVhdHVyZWNvZGUsIG1ldGgubWV0aG9kY29kZQpGUk9NIG1lYXN1cmVtZW50cmVzdWx0dmFsdWVzIG1ydgpJTk5FUiBKT0lOIHJlc3VsdHMgcmVzIE9OIG1ydi5yZXN1bHRpZCA9IHJlcy5yZXN1bHRpZApJTk5FUiBKT0lOIHZhcmlhYmxlcyB2YXIgT04gcmVzLnZhcmlhYmxlaWQgPSB2YXIudmFyaWFibGVpZApJTk5FUiBKT0lOIGZlYXR1cmVhY3Rpb25zIGZhIE9OIHJlcy5mZWF0dXJlYWN0aW9uaWQgPSBmYS5mZWF0dXJlYWN0aW9uaWQKSU5ORVIgSk9JTiBzYW1wbGluZ2ZlYXR1cmVzIHNmIE9OIHNmLnNhbXBsaW5nZmVhdHVyZWlkID0gZmEuc2FtcGxpbmdmZWF0dXJlaWQKSU5ORVIgSk9JTiBhY3Rpb25zIGFjdHMgT04gYWN0cy5hY3Rpb25pZCA9IGZhLmFjdGlvbmlkCklOTkVSIEpPSU4gdW5pdHMgdW5pdHMgT04gdW5pdHMudW5pdHNpZCA9IHJlcy51bml0c2lkCklOTkVSIEpPSU4gbWV0aG9kcyBtZXRoIE9OIG1ldGgubWV0aG9kaWQgPSBhY3RzLm1ldGhvZGlkCmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2FzaXMnfQpkYm91dCAlPiUga25pdHI6OmthYmxlKCkKYGBgCgojIyBVbmRlciB0aGUgaG9vZAoKVGhpcyBkaWFncmFtIHNob3dzIHRoZSBjb25uZWN0aW9ucyBiZXR3ZWVuIHRoZSB0YWJsZXMgdGhhdCBhcmUgcG90ZW50aWFsbHkgdXBkYXRlZCB3aGVuIGFkZGluZyBzYW1wbGVzLiBHcmF5IGJveGVzIGFyZSByZWZlcmVuY2UgdGFibGVzLCBibHVlIGJveGVzIGRlc2NyaWJlIHRoZSBhY3R1YWwgZGF0YSB2YWx1ZXMsIGFuZCB5ZWxsb3cgdGFibGVzIGRlc2NyaWJlIHRoZSBzYW1wbGUgY29sbGVjdGlvbiBhbmQgYW5hbHlzaXMuIAoKIVtdKGltZy9zYW1wbGVzLnBuZykK