2017-02-15 4 views
3

Пожалуйста, обратите внимание эти входные данные:разница между значениями величин с почти одинаковой меткой времени

  • У меня есть два инструмента (41 и 54).
  • Они измеряют давление нескольких резервуаров (T1 и T2).
  • Они измеряют давление почти в одно и то же время, но не точно.

Пример данных:

data <- data.table(
    time = as.POSIXct(paste("2017-01-01", c("11:59", "12:05", "12:02", "12:03", "14:00", "14:01", "14:02", "14:06")), tz = "GMT"), 
    instrumentId = c(41, 54, 41, 54, 41, 54, 41, 54), 
    tank = c("T1", "T1", "T2", "T2", "T1", "T1", "T2", "T2"), 
    pressure = c(25, 24, 35, 37.5, 22, 22.2, 38, 39.4)) 

Я хочу, чтобы вычислить разность между давлением, измеренным с помощью прибора 41 и прибором 54, для каждого танка, при условии, что значения, измеренные в течение 20 минут, принадлежат к одной и той же выборки ,

Идеал, метка времени разницы будет средним значением метки времени двух сравниваемых значений.

Вот скрипт используют до сих пор:

## Calculate difference of time between 2 consecutive lines 
data <- data[, timeDiff := difftime(time, shift(time, type = "lag", fill = -Inf), tz = "GMT", units = "mins"), 
        by = tank] 

# Assign the same timestamp to all the measures of a same sample 
referenceTimes <- data[timeDiff > 20, .(time)] 
data <- data[timeDiff < 20, time := referenceTimes] 

# Calculate the difference between the values measured by both instruments 
wideDt <- dcast.data.table(data,time + tank ~ instrumentId, value.var = c("pressure")) 
instruments <- as.character(unique(data$instrumentId)) 
wideDt <- wideDt[, difference := get(instruments[1]) - get(instruments[2])] 

Это делает работу, но его самая большая проблема заключается в том, что данные должны быть отсортированы надлежащим образом, в противном случае время вычисления сдвига возвращает нонсенс. С примерными входными данными это нормально, но попробуйте «unsort» их с data <- data[order(pressure)], например. В этом случае необходимо добавить data <- data[order(tank, time, instrumentId)].

Кроме того, у меня сложилось впечатление, что оно может быть более кратким, более эффективным и чистым. Одним словом, лучше использовать силу data.table.

Ожидаемый результат:

time     tank 41 54 difference 
------------------------------------------------- 
2017-01-01 11:59:00 T1 25 24.0 1.0 
2017-01-01 12:02:00 T2 35 37.5 -2.5 
2017-01-01 14:00:00 T1 22 22.2 -0.2 
2017-01-01 14:02:00 T2 38 39.4 -1.4 

Любая идея, как выполнить эту задачу правильно?

+0

Вы можете группировать каждое «время» в группе с 20-минутными интервалами ('findInterval (данные $ time, seq (данные $ time [1], данные $ time [nrow (data)], на =" 20 mins ")) ') и примените' diff (давление) 'группировку этим интервалом &" tank " –

+0

@Cath Если вы не в порядке с этим обманом, не помещайте его. Я также не отметил его как обман, так как я не уверен на 100%. – akrun

+0

@Cath Даже OP назвал свой объект 'wideDt'. – akrun

ответ

5

Вы можете легко выполнить прокатку автообъединение на два подмножества на обоих tank и time, которые не требуют какого-либо начального переназначения при задании максимального скользящего интервала (20 мин = 20 * 60 секунд)

res <- 
data[instrumentId == 54, .SD[data[instrumentId == 41], on = .(tank, time), roll = -20*60]] 
res 
#     time instrumentId tank pressure i.instrumentId i.pressure 
# 1: 2017-01-01 11:59:00   54 T1  24.0    41   25 
# 2: 2017-01-01 12:02:00   54 T2  37.5    41   35 
# 3: 2017-01-01 14:00:00   54 T1  22.2    41   22 
# 4: 2017-01-01 14:02:00   54 T2  39.4    41   38 

Тогда вычисление разности является лишь вопросом res[, difference := pressure - i.pressure]

Но если вы хотите, чтобы ваш точный нужный формат, я боюсь, что это потребует некоторого плавления/dcasting

res2 <- 
    dcast(
    melt(res, c("time", "tank"), 
     measure = patterns("instrumentId", "pressure")), 
    time + tank ~ value1, value.var = "value2" 
     )[, difference := `41` - `54`] 

res2 
#     time tank 41 54 difference 
# 1: 2017-01-01 11:59:00 T1 25 24.0  1.0 
# 2: 2017-01-01 12:02:00 T2 35 37.5  -2.5 
# 3: 2017-01-01 14:00:00 T1 22 22.2  -0.2 
# 4: 2017-01-01 14:02:00 T2 38 39.4  -1.4   
+0

Спасибо. «Ролл» был той особенностью, о которой я не знал. – Blacksad

Смежные вопросы