This is how to insert new soil moisture data from the TDR probe into the database. Click “Code” at the top of this page to download an rmarkdown version of this file!

Prepare data

Make one data frame with the data to upload where each row is data from one point without shifts in the x, y, or z location. Necessary columns are:

files <- list.files("../../Delmarva/data/sm", full.names = TRUE)
files
[1] "../../Delmarva/data/sm/Field_measurements - SOIL_field_measurements.csv"
[2] "../../Delmarva/data/sm/Soil_Moisture - July2018.csv"                    
[3] "../../Delmarva/data/sm/SoilMoisture - June2018.csv"                     
sm <- readr::read_csv(file = files[2])
Parsed with column specification:
cols(
  Date = col_character(),
  Time = col_time(format = ""),
  Site = col_character(),
  Location = col_character(),
  VWC_percent = col_double(),
  soil_EC_mscm = col_double(),
  soil_temp_C = col_double()
)

Make a Timestamp column with properly formatted dates (YYYY-MM-DD HH:MM:SS). This can be a character column or use POSIXct if you need to specify a timezone other than your computer’s current time.

sm$Timestamp <- strptime(paste(sm$Date, sm$Time), 
                         format = "%B %d, %Y %H:%M:%S", tz = "")
sm$Timestamp <- as.POSIXct(sm$Timestamp)

Make a site column with site code names

sm$site <- paste(sm$Site, sm$Location)
sm$site <- sub(pattern = "SC ", "SC-", sm$site)

Any new site names will get added to the sampling features table. If you expect that all your sites should be in the database already, use check_samplingfeaturecodes() to make sure. This function will return any site names that are not in the database. You will have to be connected to the database (see below) for it to work.

check_samplingfeaturecodes(new_codes = sm$site, db)
Date Time Site Location VWC_percent soil_EC_mscm soil_temp_C Timestamp site
July 23, 2018 08:05:00 QB SC-E 15.8 0.08 26.0 2018-07-23 08:05:00 QB SC-E
July 23, 2018 08:05:00 QB SC-E 16.9 0.03 25.7 2018-07-23 08:05:00 QB SC-E
July 23, 2018 08:05:00 QB SC-E 18.0 0.08 25.7 2018-07-23 08:05:00 QB SC-E
July 23, 2018 08:08:00 QB SC-D 38.0 0.00 25.6 2018-07-23 08:08:00 QB SC-D
July 23, 2018 08:08:00 QB SC-D 31.1 0.02 25.6 2018-07-23 08:08:00 QB SC-D
July 23, 2018 08:08:00 QB SC-D 24.9 0.00 25.6 2018-07-23 08:08:00 QB SC-D

Make sure there are no NA data values. Your data is not ready to upload if it contains NAs! If you have missing values, convert them to a numeric value (such as -9999) and specify a ‘nodatavalue’ when making the vars_list.

names(sm)[-1] %>%
  purrr::map_lgl(function(x) any(is.na(sm[[x]])))
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

Upload

Then load rodm2 and connect to the database

devtools::install_github("khondula/rodm2")
* installing *source* package ‘rodm2’ ...
** R
** inst
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
*** copying figures
** building package indices
** installing vignettes
** testing if installed package can be loaded
* DONE (rodm2)
library(rodm2)
Read 1 item

vars list

Make a list with the necessary information about each variable with the following format:

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

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.

get_cv_terms("variablename")
get_cv_terms("units")
vars_list <- list("Volumetric water content" = 
                    list(column ="VWC_percent", units = "Percent"),
                   "Bulk electrical conductivity" = 
                    list(column = "soil_EC_mscm", units = "Millisiemen per Centimeter"),
                   "Temperature" = 
                    list(column = "soil_temp_C", units = "Degree Celsius"))

upload measurements function

Use db_insert_results_m() to upload the data. The arguments actionby and equipment_name are optional. For processed data, specify a value for processinglevel (the default is “Raw data”).

db_insert_results_m(db = db,
                     datavalues = sm,
                     method = "soilmoistureTDR",
                     site_code_col = "site",
                     variables = vars_list,
                     actionby = "Kelly",
                     sampledmedium = "Soil")

Helper functions

The method and site code will be added to the database if they do not already exist. If the values supplied for actionby or equipment_name do not already exist in the database, you will also need to supply the required arguments to db_descrbie_person() or db_describe_equipment().

If you want to see if a site code exists in the database already, use check_samplingfeaturecodes to returns the names of any sites NOT in the database compared to a given vector, or get_site_names_like() for approximate string matching for sites that ARE in the database.

check_samplingfeaturecodes(new_codes = "ND", db = db)
get_site_names_like(x = "QB well", db = db)

To see the current methods, people, or equipment in the database, use db_get_%() functions:

db_get_equipment(db)
db_get_people(db)
db_get_methods(db)
LS0tCnRpdGxlOiAiSW5zZXJ0IHNvaWwgbW9pc3R1cmUgZGF0YSwgdjIiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KClRoaXMgaXMgaG93IHRvIGluc2VydCBuZXcgc29pbCBtb2lzdHVyZSBkYXRhIGZyb20gdGhlIFREUiBwcm9iZSBpbnRvIHRoZSBkYXRhYmFzZS4gQ2xpY2sgIkNvZGUiIGF0IHRoZSB0b3Agb2YgdGhpcyBwYWdlIHRvIGRvd25sb2FkIGFuIHJtYXJrZG93biB2ZXJzaW9uIG9mIHRoaXMgZmlsZSEgCgojIFByZXBhcmUgZGF0YQoKTWFrZSBvbmUgZGF0YSBmcmFtZSB3aXRoIHRoZSBkYXRhIHRvIHVwbG9hZCB3aGVyZSBlYWNoIHJvdyBpcyBkYXRhIGZyb20gb25lIHBvaW50IHdpdGhvdXQgc2hpZnRzIGluIHRoZSB4LCB5LCBvciB6IGxvY2F0aW9uLiBOZWNlc3NhcnkgY29sdW1ucyBhcmU6CgoqIFRpbWVzdGFtcCBjb2x1bW4gd2l0aCBkYXRldGltZSBmb3JtYXR0ZWQgYXMgWVlZWS1NTS1ERCBISDpNTTpTUwoqIE9uZSBjb2x1bW4gZm9yIGVhY2ggb2YgdGhlIHZhcmlhYmxlcyBtZWFzdXJlZAoqIEEgY29sdW1uIHdpdGggc2l0ZSBjb2RlIG5hbWVzCgpgYGB7cn0KZmlsZXMgPC0gbGlzdC5maWxlcygiLi4vLi4vRGVsbWFydmEvZGF0YS9zbSIsIGZ1bGwubmFtZXMgPSBUUlVFKQpgYGAKCmBgYHtyfQpmaWxlcwpgYGAKCmBgYHtyfQpzbSA8LSByZWFkcjo6cmVhZF9jc3YoZmlsZSA9IGZpbGVzWzJdKQpgYGAKCk1ha2UgYSBUaW1lc3RhbXAgY29sdW1uIHdpdGggcHJvcGVybHkgZm9ybWF0dGVkIGRhdGVzIChZWVlZLU1NLUREIEhIOk1NOlNTKS4gVGhpcyBjYW4gYmUgYSBjaGFyYWN0ZXIgY29sdW1uIG9yIHVzZSBQT1NJWGN0IGlmIHlvdSBuZWVkIHRvIHNwZWNpZnkgYSB0aW1lem9uZSBvdGhlciB0aGFuIHlvdXIgY29tcHV0ZXIncyBjdXJyZW50IHRpbWUuIAoKYGBge3J9CnNtJFRpbWVzdGFtcCA8LSBzdHJwdGltZShwYXN0ZShzbSREYXRlLCBzbSRUaW1lKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXQgPSAiJUIgJWQsICVZICVIOiVNOiVTIiwgdHogPSAiIikKc20kVGltZXN0YW1wIDwtIGFzLlBPU0lYY3Qoc20kVGltZXN0YW1wKQpgYGAKCk1ha2UgYSBzaXRlIGNvbHVtbiB3aXRoIHNpdGUgY29kZSBuYW1lcwoKYGBge3J9CnNtJHNpdGUgPC0gcGFzdGUoc20kU2l0ZSwgc20kTG9jYXRpb24pCnNtJHNpdGUgPC0gc3ViKHBhdHRlcm4gPSAiU0MgIiwgIlNDLSIsIHNtJHNpdGUpCmBgYApBbnkgbmV3IHNpdGUgbmFtZXMgd2lsbCBnZXQgYWRkZWQgdG8gdGhlIHNhbXBsaW5nIGZlYXR1cmVzIHRhYmxlLiBJZiB5b3UgZXhwZWN0IHRoYXQgYWxsIHlvdXIgc2l0ZXMgc2hvdWxkIGJlIGluIHRoZSBkYXRhYmFzZSBhbHJlYWR5LCB1c2UgYGNoZWNrX3NhbXBsaW5nZmVhdHVyZWNvZGVzKClgIHRvIG1ha2Ugc3VyZS4gVGhpcyBmdW5jdGlvbiB3aWxsIHJldHVybiBhbnkgc2l0ZSBuYW1lcyB0aGF0IGFyZSBub3QgaW4gdGhlIGRhdGFiYXNlLiBZb3Ugd2lsbCBoYXZlIHRvIGJlIGNvbm5lY3RlZCB0byB0aGUgZGF0YWJhc2UgKHNlZSBiZWxvdykgZm9yIGl0IHRvIHdvcmsuIAoKYGBge3IsIGV2YWwgPSBGQUxTRX0KY2hlY2tfc2FtcGxpbmdmZWF0dXJlY29kZXMobmV3X2NvZGVzID0gc20kc2l0ZSwgZGIpCmBgYAoKYGBge3IgZWNobz1GQUxTRSwgcmVzdWx0cz0nYXNpcyd9CmhlYWQoc20pICU+JSBrbml0cjo6a2FibGUoKQpgYGAKCk1ha2Ugc3VyZSB0aGVyZSBhcmUgbm8gTkEgZGF0YSB2YWx1ZXMuIFlvdXIgZGF0YSBpcyBub3QgcmVhZHkgdG8gdXBsb2FkIGlmIGl0IGNvbnRhaW5zIE5BcyEgSWYgeW91IGhhdmUgbWlzc2luZyB2YWx1ZXMsIGNvbnZlcnQgdGhlbSB0byBhIG51bWVyaWMgdmFsdWUgKHN1Y2ggYXMgLTk5OTkpIGFuZCBzcGVjaWZ5IGEgJ25vZGF0YXZhbHVlJyB3aGVuIG1ha2luZyB0aGUgYHZhcnNfbGlzdGAuIAoKYGBge3J9Cm5hbWVzKHNtKVstMV0gJT4lCiAgcHVycnI6Om1hcF9sZ2woZnVuY3Rpb24oeCkgYW55KGlzLm5hKHNtW1t4XV0pKSkKYGBgCgojIFVwbG9hZAoKVGhlbiBsb2FkIGByb2RtMmAgYW5kIGNvbm5lY3QgdG8gdGhlIGRhdGFiYXNlCmBgYHtyLCBtZXNzYWdlPUZBTFNFfQpkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoImtob25kdWxhL3JvZG0yIikKbGlicmFyeShyb2RtMikKYGBgCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgY29tbWVudD1OVUxMfQpsaWJyYXJ5KFJQb3N0Z3JlU1FMKQpwYXNzd29yZCA8LSBzY2FuKCIucGdwYXNzIiwgd2hhdD0iIikKZGIgPC0gZGJDb25uZWN0KFBvc3RncmVTUUwoKSwgCiAgICAgICAgICAgICAgICBob3N0ID0gInNlc3luYy1wb3N0Z2lzMDEucmVzZWFyY2guc2VzeW5jLm9yZyIsCiAgICAgICAgICAgICAgICBkYm5hbWUgPSAiY2hvcHRhbmsiLCAKICAgICAgICAgICAgICAgIHVzZXIgPSAicGFsbWVyZ3JvdXAiLAogICAgICAgICAgICAgICAgcGFzc3dvcmQgPSBwYXNzd29yZCkKYGBgCgoKPiAqKnZhcnMgbGlzdCoqCgpNYWtlIGEgbGlzdCB3aXRoIHRoZSBuZWNlc3NhcnkgaW5mb3JtYXRpb24gYWJvdXQgZWFjaCB2YXJpYWJsZSB3aXRoIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgoKYGBgCmxpc3QoIlZhcmlhYmxlMSBOYW1lIiA9IGxpc3QoY29sdW1uID0gIkNvbHVtbk5hbWUiLCB1bml0cyA9ICJVbml0cyBOYW1lIiksCiAgICAgIlZhcmlhYmxlMiBOYW1lIiA9IGxpc3QoY29sdW1uID0gIkNvbHVtbk5hbWUiLCB1bml0cyA9ICJVbml0cyBOYW1lIikpCmBgYAoKSWYgdGhlIGNvbHVtbiBuYW1lIGlzIHRoZSBleGFjdCBuYW1lIG9mIHRoZSB2YXJpYWJsZSBmcm9tIHRoZSBjb250cm9sbGVkIHZvY2FidWxhcnkgKGkuZS4gd2l0aCBzcGFjZXMgYW5kIGNvcnJlY3QgY2FwaXRhbGl6YXRpb24pLCBgY29sdW1uYCBkb2VzIG5vdCBuZWVkIHRvIGJlIHNwZWNpZmllZC4gSWYgdGhlcmUgYXJlIGNvbHVtbnMgaW4geW91ciBkYXRhIHRoYXQgaGF2ZSBkYXRhIHF1YWxpdHkgY29kZXMgb3IgY2Vuc29yIGNvZGVzLCB0aG9zZSBzaG91bGQgYmUgc3BlY2lmaWVkIGhlcmUgYXMgYHF1YWxpdHljb2RlY29sYCBhbmQgYGNlbnNvcmNvZGVjb2xgIHJlc3BlY3RpdmVseS4gWW91IGNhbiBhbHNvIHNwZWNpZnkgYSBgdmFyaWFibGV0eXBlY3ZgLCBgdmFyaWFibGVkZWZpbml0aW9uYCBhbmQgYG5vZGF0YXZhbHVlYCBmb3IgdmFyaWFibGVzIHRoYXQgaGF2ZW4ndCBiZWVuIGVudGVyZWQgdG8gdGhlIGRhdGFiYXNlIGJlZm9yZS4KClZhcmlhYmxlIG5hbWVzIGFuZCB1bml0cyBuYW1lcyBuZWVkIHRvIGJlIGZyb20gdGhlIGNvbnRyb2xsZWQgdm9jYWJ1bGFyaWVzLiBUbyBzZWUgdGhlc2Ugb3B0aW9ucywgdXNlIHRoZSBgZ2V0X2N2X3Rlcm1zKClgIGZ1bmN0aW9uLiAKCmBgYHtyLCBldmFsPUZBTFNFfQpnZXRfY3ZfdGVybXMoInZhcmlhYmxlbmFtZSIpCmdldF9jdl90ZXJtcygidW5pdHMiKQpgYGAKCmBgYHtyfQp2YXJzX2xpc3QgPC0gbGlzdCgiVm9sdW1ldHJpYyB3YXRlciBjb250ZW50IiA9IAogICAgICAgICAgICAgICAgICAgIGxpc3QoY29sdW1uID0iVldDX3BlcmNlbnQiLCB1bml0cyA9ICJQZXJjZW50IiksCiAgICAgICAgICAgICAgICAgICAiQnVsayBlbGVjdHJpY2FsIGNvbmR1Y3Rpdml0eSIgPSAKICAgICAgICAgICAgICAgICAgICBsaXN0KGNvbHVtbiA9ICJzb2lsX0VDX21zY20iLCB1bml0cyA9ICJNaWxsaXNpZW1lbiBwZXIgQ2VudGltZXRlciIpLAogICAgICAgICAgICAgICAgICAgIlRlbXBlcmF0dXJlIiA9IAogICAgICAgICAgICAgICAgICAgIGxpc3QoY29sdW1uID0gInNvaWxfdGVtcF9DIiwgdW5pdHMgPSAiRGVncmVlIENlbHNpdXMiKSkKCmBgYAoKPiAqKnVwbG9hZCBtZWFzdXJlbWVudHMgZnVuY3Rpb24qKgoKVXNlIGBkYl9pbnNlcnRfcmVzdWx0c19tKClgIHRvIHVwbG9hZCB0aGUgZGF0YS4gVGhlIGFyZ3VtZW50cyBgYWN0aW9uYnlgIGFuZCBgZXF1aXBtZW50X25hbWVgIGFyZSBvcHRpb25hbC4gRm9yIHByb2Nlc3NlZCBkYXRhLCBzcGVjaWZ5IGEgdmFsdWUgZm9yIGBwcm9jZXNzaW5nbGV2ZWxgICh0aGUgZGVmYXVsdCBpcyAiUmF3IGRhdGEiKS4gCgpgYGB7ciwgZXZhbCA9IEZBTFNFfQpkYl9pbnNlcnRfcmVzdWx0c19tKGRiID0gZGIsCiAgICAgICAgICAgICAgICAgICAgIGRhdGF2YWx1ZXMgPSBzbSwKICAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gInNvaWxtb2lzdHVyZVREUiIsCiAgICAgICAgICAgICAgICAgICAgIHNpdGVfY29kZV9jb2wgPSAic2l0ZSIsCiAgICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlcyA9IHZhcnNfbGlzdCwKICAgICAgICAgICAgICAgICAgICAgYWN0aW9uYnkgPSAiS2VsbHkiLAogICAgICAgICAgICAgICAgICAgICBzYW1wbGVkbWVkaXVtID0gIlNvaWwiKQoKYGBgCgojIyMgSGVscGVyIGZ1bmN0aW9ucwoKVGhlIG1ldGhvZCBhbmQgc2l0ZSBjb2RlIHdpbGwgYmUgYWRkZWQgdG8gdGhlIGRhdGFiYXNlIGlmIHRoZXkgZG8gbm90IGFscmVhZHkgZXhpc3QuIElmIHRoZSB2YWx1ZXMgc3VwcGxpZWQgZm9yIGBhY3Rpb25ieWAgb3IgYGVxdWlwbWVudF9uYW1lYCBkbyBub3QgYWxyZWFkeSBleGlzdCBpbiB0aGUgZGF0YWJhc2UsIHlvdSB3aWxsIGFsc28gbmVlZCB0byBzdXBwbHkgdGhlIHJlcXVpcmVkIGFyZ3VtZW50cyB0byBgZGJfZGVzY3JiaWVfcGVyc29uKClgIG9yIGBkYl9kZXNjcmliZV9lcXVpcG1lbnQoKWAuIAoKSWYgeW91IHdhbnQgdG8gc2VlIGlmIGEgc2l0ZSBjb2RlIGV4aXN0cyBpbiB0aGUgZGF0YWJhc2UgYWxyZWFkeSwgdXNlIGBjaGVja19zYW1wbGluZ2ZlYXR1cmVjb2Rlc2AgdG8gcmV0dXJucyB0aGUgbmFtZXMgb2YgYW55IHNpdGVzIE5PVCBpbiB0aGUgZGF0YWJhc2UgY29tcGFyZWQgdG8gYSBnaXZlbiB2ZWN0b3IsIG9yIGBnZXRfc2l0ZV9uYW1lc19saWtlKClgIGZvciBhcHByb3hpbWF0ZSBzdHJpbmcgbWF0Y2hpbmcgZm9yIHNpdGVzIHRoYXQgQVJFIGluIHRoZSBkYXRhYmFzZS4gCgpgYGB7ciwgd2FybmluZz1GQUxTRX0KY2hlY2tfc2FtcGxpbmdmZWF0dXJlY29kZXMobmV3X2NvZGVzID0gIk5EIiwgZGIgPSBkYikKYGBgCgpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KZ2V0X3NpdGVfbmFtZXNfbGlrZSh4ID0gIlFCIHdlbGwiLCBkYiA9IGRiKQpgYGAKClRvIHNlZSB0aGUgY3VycmVudCBtZXRob2RzLCBwZW9wbGUsIG9yIGVxdWlwbWVudCBpbiB0aGUgZGF0YWJhc2UsIHVzZSBgZGJfZ2V0XyUoKWAgZnVuY3Rpb25zOgoKYGBge3J9CmRiX2dldF9lcXVpcG1lbnQoZGIpCmRiX2dldF9wZW9wbGUoZGIpCmRiX2dldF9tZXRob2RzKGRiKQpgYGAKCg==