Common calculations

Description

Various common calculations associated with PEMS data.

Usage

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
calcDistance(speed = NULL, time = NULL, data = NULL, 
          ..., fun.name = "calcDistance", hijack= FALSE)

calcSpeed(distance = NULL, time = NULL, data = NULL, 
          ..., fun.name = "calcSpeed", hijack= FALSE)


calcAccel(speed = NULL, time = NULL, data = NULL, 
          ..., fun.name = "calcAccel", hijack= FALSE)

calcAcceleration(...)

calcJerk(accel = NULL, time = NULL, data = NULL, 
          ..., fun.name = "calcJerk", hijack= FALSE)

#associated

calcChecks(fun.name = "calcChecks", ..., data = NULL,
          if.missing = c("stop", "warning", "return"), 
          output = c("input", "data.frame", "pems", "special"),
          unit.conversions = NULL, overwrite = FALSE)

calcPack(output = NULL, data = NULL, settings = NULL, 
          fun.name = "calcPack", this.call = NULL)

Arguments

speed, time, distance, accel

(Required data series typically vectors) The inputs to use when doing a calculation. These can typically be vectors or elements in either a data.frame or pems object.

data

(Optional data.frame or pems object) The data source if either a data.frame or pems object is being used.

...

(Optional) Other arguments, currently passed on to calcChecks.

fun.name

(Optional character) The name of the parent function, to be used in error messaging.

hijack

(Logical) Is this function being locally 'hijacked' by a user/function developer? See Note on hijack below.

if.missing, output, unit.conversions, overwrite, settings, this.call

(Various) Along with data and fun.name, arguments used by calcCheck and calcPack to manage error and unit handling and workhorse calc... operations. These are typically passed to the appropriate check... or ...Units function for evaluation. See Details, Note and Examples below.

Details

With the exception of calcChecks, calc... functions do common calculations.

calcDistance calculates distance (in m) using speed and time.

calcSpeed calculates speed (in m/s) using distance and time.

calcAccel calculates acceleration (in m/s/s) using speed and time.

calcJerk calculates jerk (rate of change of acceleration in m/s/s/s) using acceleration and time.

By default results are returned as pems.elements. Other options include returning as the original data plus the results as either a data.frame or a pems object. One final option is to return the results in the supplied format. So, for example, uf: inputs are supplied as vectors, the answer is returned as a vector; If inputs are supplied in a pems object, that pems object is returned with the answer added in. This behaviour is enabled by the default output = "special".

Unit management is by convertUnits. See Note below.

The extra functions calcChecks and calcPack are add-ins that anyone can use to develop other similiar functions. They are add at the start and end of standard calc... functions to provide a 'minimal code' mechanism for the integrating of third-party code. See Note and Example 3 below.

Value

With the exception of calcChecks and calcPack, all calc... functions return either a vector, data.frame or pems object, depending on output and data settings.

Note

Unit handling in pems.utils is via checkUnits, getUnits, setUnits and convertUnits. Allowed unit conversion methods have to be defined in ref.unit.conversions or a locally defined alternative supplied by the user. See convertUnits for an example of how to locally work with unit conversions.

hijack is an in-development argument, supplied to allow code developers to run multiple functions in different function environments. When developers 'mix and match' code from several sources it can become unstable, especially if functions are run within functions within functions, etc. hijack = TRUE and associated code makes a function local to 'side-step' this issue. This work by assuming/expecting all inputs to be local, i.e. supplied directly by the code user. See Example 3 below.

Author(s)

Karl Ropkins

References

References in preparation.

See Also

calcVSP for VSP calculations. calcEm for emissions calculations.

getElement (checkInput if passing elements as inputs), checkUnits and convertUnits for data management.

Examples

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
###########
##example 1 
###########

#basic usage

#calculated accel as pems.element

calcAccel(velocity, local.time, pems.1)

#answer returned as suppied pems + calculated accel

calcAccel(velocity, local.time, pems.1, output = "pems")

#or, if you would rather... 
#ans <- pems.1
#ans$accel <- calcAccel(velocity, local.time, pems.1)


###########
#example 2
###########

#making wrappers for routine data processing 

my.pems <- list(pems.1, pems.1)

sapply(my.pems, function(x) 
                  calcAccel(velocity, local.time, data=x))

#ans = accel data series for each pems in my.pems list

#             [,1]        [,2]
# [1,]  0.00000000  0.00000000
# [2,]  0.00000000  0.00000000
# [3,]  0.05555556  0.05555556
# [4,]  0.00000000  0.00000000
# [5,] -0.02777778 -0.02777778
# [6,]  0.05555556  0.05555556
# ...

#or
#lapply(my.pems, function(x) 
#                  calcAccel(velocity, local.time, data=x, output="pems"))
#for output as a list of pems objects with accel added to each

#note:
#sapply if you can/want to simiplify outputs
#lapply if you want to keep output as a list of answers


###########
#example 3
###########

#making a function that allows third party hijack
#and pems management

my.fun <- function(speed, time, data = NULL, hijack = FALSE, 
                   ..., fun.name = "my.function"){

    #setup
    this.call <- match.call()
    
    #run checks
    settings <- calcChecks(fun.name, ..., data = data)
    
    #get pems elements if not already got
    if(!hijack){
 
        #the check handle errors and error messaging
        #checkInput 
        speed <- checkInput(speed, data, fun.name = fun.name,   
                            if.missing = settings$if.missing,
                            unit.conversions = settings$unit.conversions)

        time <- checkInput(time, data, fun.name = fun.name,   
                            if.missing = settings$if.missing,
                            unit.conversions = settings$unit.conversions)
    }

    #any extra error/missing case handling? 

    #run 'hijacked' code

    #reset units to what you want
    #... allows you to pass local unit.conversions
    speed <- convertUnits(speed, to = "km/h", hijack = TRUE, 
                          if.missing = settings$if.missing,
                          unit.conversions = settings$unit.conversions)

    #use someone else's calculation
    distance <- calcDistance(speed, time, hijack = TRUE, 
                          if.missing = settings$if.missing,
                          unit.conversions = settings$unit.conversions)

    #do other stuff?

    #reset units again?

    #output
    #calcPack handling the output type  
    #and my pems history tracking if data modified
    calcPack(output = distance, data = data, settings = settings, 
             fun.name = fun.name, this.call = this.call)     

}

ans <- my.fun(velocity, local.time, pems.1, output="pems")

#seems long winded but gives you control of 
##the error handling, unit management, and output type
##and (if working in pems objects) history logging 

##and lets you do this

ans <- lapply(my.pems, function(x) 
                  my.fun(velocity, local.time, data=x, output="pems"))

#which will not always work if you are running 
#functions in functions, especially if those functions
#are also running functions in functions...