Creates a new virtual sensor on locality/logger in the myClim object. Values are computed by a user-defined function or an expression evaluated on a data table containing datetime and sensor columns.

mc_calc_custom(
  data,
  custom_function,
  output_sensor,
  output_sensor_id = NULL,
  logger_type = NULL,
  localities = NULL,
  sensors = NULL
)

Arguments

data

cleaned myClim object see myClim-package

custom_function

Function or unquoted expression defining the calculation.

  • Function (named or anonymous): first argument is data_table (tibble with datetime and sensor columns); must return a vector of logical, integer, or numeric. Return NULL to skip the item.

  • Expression: unquoted R expression referencing sensor names as variables (e.g. TMS_T1 - TMS_T3, mean(TMS_T1)). Evaluated per locality/logger using rlang::eval_tidy().

output_sensor

Name of the newly created virtual sensor.

output_sensor_id

Output sensor_id (optional). If NULL (default), sensor_id is inferred from custom function output type (logical, integer, real). Must be one of names(mc_data_sensors) when provided.

logger_type

Logger type filter (optional). Character vector of logger types to process (e.g. c("TMS","Thermo")) In raw format this filters loggers; in agg format it determines default sensors when sensors=NULL.

localities

Character vector of locality_ids to process. NULL (default) processes all localities.

sensors

Character vector of sensor names that must all be present in a logger/locality for processing to occur. Items missing any of these sensors are silently skipped. NULL (default) disables this check.

Value

The input myClim object with the new virtual sensor output_sensor added to all eligible localities/loggers.

Details

The user function receives a tibble with columns datetime and one column per sensor present at each logger (raw format) or locality (agg format). It must return a logical/integer/numeric vector with the same length as number of rows. To skip loggers/localities without sensors used in custom function, use the sensors parameter.

When custom function is provided as an unquoted expression (as in dplyr::mutate()), it is evaluated by rlang::eval_tidy() with the data table as data mask, so sensor names can be used directly (e.g. TMS_T1 - 2 * TMS_T3). Pronouns .data and .env are available to distinguish sensor columns from variables in the calling environment (e.g. .data$TMS_T1 - .env$offset). Standard R functions (mean(), dplyr::lag(), abs(), etc.) are available. If the calculation fails (e.g. a referenced sensor is missing), the function stops with an error naming the locality (and logger in raw format). Use sensors parameter to skip loggers/localities without required sensors.

Examples

# Function form - calculate difference between air and soil temperature
diff_func <- function(data_table) {
    data_table$TMS_T1 - data_table$TMS_T3
}
data_diff <- mc_calc_custom(
    mc_data_example_clean,
    custom_function = diff_func,
    output_sensor = "DIFF_T1_T3",
    output_sensor_id = "T_C",
    logger_type   = "TMS",
    sensors       = c("TMS_T1", "TMS_T3")
)
# \donttest{
mc_plot_line(data_diff, sensors = c("DIFF_T1_T3","TMS_T1","TMS_T3"))

# }

# Expression form - equivalent result
data_diff <- mc_calc_custom(
    mc_data_example_clean,
    custom_function = TMS_T1 - TMS_T3,
    output_sensor   = "DIFF_T1_T3",
    output_sensor_id = "T_C",
    logger_type     = "TMS",
    sensors         = c("TMS_T1", "TMS_T3")
)
# \donttest{
mc_plot_line(data_diff, sensors = c("DIFF_T1_T3","TMS_T1","TMS_T3"))

# }

# Expression form - identify rain events based on TMS moisture sensor
# (moisture increase > 50 units within 4 consecutive measurements)
rain_event <- mc_calc_custom(
    mc_data_example_clean,
    custom_function = ifelse(dplyr::lead(TMS_moist, 4) - TMS_moist > 50, 1, 0),
    output_sensor = "RAIN",
    sensors       = c("TMS_moist")
)
# \donttest{
mc_plot_line(rain_event, sensors = c("TMS_moist","RAIN"))
#> Warning: Removed 8 rows containing missing values or values outside the scale range
#> (`geom_line()`).

# }