【发布时间】:2018-06-18 12:11:10
【问题描述】:
我不熟悉 R 中的循环,并且有一个相对简单的数据集要处理。我的示例数据集包含时间戳 - time,手机 ID:id,以及手机电池电量:level
我的目标是产生一个输出,该输出采用电池随时间下降的速度,同时考虑到充电周期。可以识别循环的开始,其中下一个记录的级别高于前一个。换句话说,虽然level lag(level),循环应该继续,但只要level > lag(level),循环应该重新开始
> test
time id level
1: 2017-12-25 14:10:03 1 81
2: 2017-12-25 14:20:03 1 81
3: 2017-12-25 14:30:04 1 81
4: 2017-12-25 14:40:04 1 73
5: 2017-12-25 14:50:04 1 70
6: 2017-12-25 15:00:03 1 70
7: 2017-12-25 15:10:04 1 65
8: 2017-12-25 15:20:04 1 62
9: 2017-12-25 15:30:04 1 61
10: 2017-12-25 15:40:04 1 60
11: 2017-12-25 15:50:03 1 60
12: 2017-12-25 16:00:04 1 60
13: 2017-12-25 16:10:04 1 95
14: 2017-12-25 16:20:03 1 95
15: 2017-12-25 16:30:04 1 95
16: 2017-12-25 16:40:04 1 94
17: 2017-12-25 16:50:04 1 92
18: 2017-12-25 17:00:03 1 90
19: 2017-12-25 17:10:04 1 81
20: 2017-12-25 17:20:03 1 79
21: 2017-12-25 17:30:03 2 100
22: 2017-12-25 17:40:03 2 100
23: 2017-12-25 17:50:03 2 100
24: 2017-12-25 18:00:03 2 90
25: 2017-12-25 18:10:03 2 85
26: 2017-12-25 18:20:03 2 75
27: 2017-12-25 18:30:04 2 65
28: 2017-12-25 18:40:03 2 54
29: 2017-12-25 18:50:03 2 32
30: 2017-12-25 19:00:03 2 11
31: 2017-12-25 19:10:04 2 92
32: 2017-12-25 19:20:04 2 92
33: 2017-12-25 19:30:03 2 91
34: 2017-12-25 19:40:04 2 90
35: 2017-12-25 19:50:04 2 90
36: 2017-12-25 20:00:03 2 81
37: 2017-12-25 20:10:03 2 79
38: 2017-12-25 20:20:04 2 99
39: 2017-12-25 20:30:04 2 96
40: 2017-12-25 20:40:03 2 96
在上面的示例数据集中,预期输出如下所示,其中difftime = 循环开始和停止的时间差,diffcharge = 循环开始和停止的电池电量差, 和 rate = diffcharge/difftime
> outcome
id start recharge difftime diffcharge rate
1 1 2017-12-25 14:10:03 2017-12-25 16:00:04 110.0167 21 0.1908801
2 1 2017-12-25 16:10:04 2017-12-25 17:20:03 69.98333 16 0.2286259
3 2 2017-12-25 17:30:03 2017-12-25 19:00:03 90 89 0.9888889
4 2 2017-12-25 19:10:04 2017-12-25 20:10:03 59.98333 13 0.2167269
5 2 2017-12-25 20:20:04 2017-12-25 20:40:03 19.98333 3 0.1501251
到目前为止,我只是尝试创建一个连接每个循环的级别的 while 循环,之后我可以使用以下代码获取最小值、最大值等,但这不会产生预期的输出。
raw_data <- test
unique_id = unique(test$id)
for (id in unique_id)
{
onePhone <- raw_data[ which(raw_data$id == id), ]
onePhone <- onePhone[order(onePhone$time, decreasing = FALSE),]
cycle <- NULL
if(nrow(onePhone) >=2 ){
for(i in 2:nrow(onePhone)) {
while(onePhone[i-1,"level"] >= onePhone[i,"level"])
{
i = i+1
cycle <- c(z, onePhone[i,"level"])
}
print(cycle)
}
}
}
任何关于如何使用 data.table、dplyr 或简单的 while 循环的建议将不胜感激。这是示例数据:
> dput(test)
structure(list(time = structure(c(1514229003.91212, 1514229603.61297,
1514230204.14629, 1514230804.81938, 1514231404.36784, 1514232003.73393,
1514232604.17933, 1514233204.00143, 1514233804.68755, 1514234404.15599,
1514235003.99419, 1514235604.68204, 1514236204.18828, 1514236803.66526,
1514237404.0434, 1514238004.40609, 1514238604.02003, 1514239203.42238,
1514239804.19495, 1514240403.15927, 1514241003.87092, 1514241603.93167,
1514242203.77223, 1514242803.66758, 1514243403.33705, 1514244003.25017,
1514244604.05367, 1514245203.7921, 1514245803.2651, 1514246403.63888,
1514247004.02684, 1514247604.04009, 1514248203.99929, 1514248804.07401,
1514249404.11004, 1514250003.74613, 1514250603.88962, 1514251204.19115,
1514251804.06932, 1514252403.94181), class = c("POSIXct", "POSIXt"
), tzone = "EST"), id = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2), level = c(81, 81, 81, 73, 70, 70, 65, 62,
61, 60, 60, 60, 95, 95, 95, 94, 92, 90, 81, 79, 100, 100, 100,
90, 85, 75, 65, 54, 32, 11, 92, 92, 91, 90, 90, 81, 79, 99, 96,
96)), .Names = c("time", "id", "level"), class = c("data.table",
"data.frame"), row.names = c(NA, -40L), .internal.selfref = <pointer: 0x102010778>)
【问题讨论】:
标签: r while-loop dplyr data.table