我希望使用data.table
检测“冻结”的传感器数据。为此,我可以检查最近3天的数据,看看对于给定的列,该数据是否相同。我希望输出是被冻结的传感器的UID,然后是被冻结的传感器流的名称(即“温度”,“压力”等)。
示例:我有以下data.table:
library(data.table)
dt <- data.table(UID = c(1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3),
report_date = rep(seq.Date(as.Date("2019/1/1"), as.Date("2019/1/6"), 'days'), 3),
temperature = c(101,103,105,101,105,104,105,103,101,102,102, 102,103,101,102,105,106,111),
pressure = c(10.2,10.4,10.7,10.5,10.1,10.2,10.1,10.5,10.11,10.22,10.11,10.11,10.1,10.1,10.1,10.3,10.3,10.3),
voltage = c(0.023,0.025,0.011,0.013,0.0254,0.028,0.028,0.077,0.026,0.0236,0.0258,0.0214,0.089,0.034,0.0387,0.0654,0.0246,0.02133))
dt
UID report_date temperature pressure voltage
1: 1 2019-01-01 101 10.20 0.02300
2: 1 2019-01-02 103 10.40 0.02500
3: 1 2019-01-03 105 10.70 0.01100
4: 1 2019-01-04 101 10.50 0.01300
5: 1 2019-01-05 105 10.10 0.02540
6: 1 2019-01-06 104 10.20 0.02800
7: 2 2019-01-01 105 10.10 0.02800
8: 2 2019-01-02 103 10.50 0.07700
9: 2 2019-01-03 101 10.11 0.02600
10: 2 2019-01-04 102 10.22 0.02360
11: 2 2019-01-05 102 10.11 0.02580
12: 2 2019-01-06 102 10.11 0.02140
13: 3 2019-01-01 103 10.10 0.08900
14: 3 2019-01-02 101 10.10 0.03400
15: 3 2019-01-03 102 10.10 0.03870
16: 3 2019-01-04 105 10.30 0.06540
17: 3 2019-01-05 106 10.30 0.02460
18: 3 2019-01-06 111 10.30 0.02133
输出应产生2行,即ID = 2和colID =“ temperature”的2行和ID = 3和colID =“ pressure”的2行。因为温度在ID = 2的最后3天中自身重复了3次ID等于3的压力。
UID colID
1. 2 temperature
2. 3 pressure
我可以想到使用基数R和循环执行此操作的方法,但是对于正确的data.table
方法却迷茫了。
答案 0 :(得分:4)
您可以使用
frozen = function(x) uniqueN(tail(x, 3)) == 1
dt[, .(colID = c(
'temperature'[frozen(temperature)],
'pressure'[frozen(pressure)])),
by=UID]
# UID colID
# 1: 2 temperature
# 2: 3 pressure
另一种版本是在对冻结的变量进行子设置之前融化数据。如果有很多测量变量,而不仅仅是如您示例中的温度和压力,这可能会更简洁。
cols = c('temperature', 'pressure')
dtm = melt(dt, id = 'UID', measure = cols)
dtm[, frozen(value), by = .(UID, variable)][(V1)]
有多种方法可以测试同一向量的元素之间的相等性。查看答案here,了解一些选项。最好的方法取决于您的实际需求。像上面一样,使用UniqueN
可以检查浮点数是否相同,是否确实冻结了这些值。根据您的特定用例以及仪器的工作方式,您可能更愿意根据不同的标准(例如,在绝对或相对机器公差范围内几乎相同)检查它们是否“相同”。对于某些细微差别,请务必阅读this answer上的评论。
如果您决定进行其他测试,只需在上面我使用UniqueN
的地方替换它即可。
答案 1 :(得分:2)
对于较大的数据集和UID应该是快速的:
> dt[, .SD
][, melt(.SD, id.vars=c('UID', 'report_date'))
][order(UID, variable, -report_date)
][, rowid := rowid(UID, variable)
][rowid <= 3
][, .N, .(UID, variable, value)
][N == 3
][, setnames(.SD, 'variable', 'colID')
][, N := NULL
][, value := NULL
][]
UID colID
1: 2 temperature
2: 3 pressure
>