R 而使用data.table循环条件
我不熟悉R中的循环,有一个相对简单的数据集要处理。我的示例数据集由时间戳-R 而使用data.table循环条件,r,while-loop,dplyr,data.table,R,While Loop,Dplyr,Data.table,我不熟悉R中的循环,有一个相对简单的数据集要处理。我的示例数据集由时间戳-时间、手机id:id、手机电池电量:电量 我的目标是生成一个输出,该输出考虑了电池随时间的衰减率,并考虑了充电周期。当以下记录的级别大于前一记录的级别时,可以确定周期的开始。换句话说,当水平滞后(水平)时,循环应重新开始 > test time id level 1: 2017-12-25 14:10:03 1 81 2: 2017-12-25 14:20:03 1
时间
、手机id:id
、手机电池电量:电量
我的目标是生成一个输出,该输出考虑了电池随时间的衰减率,并考虑了充电周期。当以下记录的级别大于前一记录的级别时,可以确定周期的开始。换句话说,当水平滞后(水平)
时,循环应重新开始
> 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循环来连接每个循环的级别,之后我可以使用下面的代码获取min、max等,但这不会产生预期的输出
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)
}
}
}
如果test
是一个data.table
,则可以将cumsum
与shift
一起使用。(shift
是来自data.table
的函数;它与lag
相同)
如果test
是一个data.table
,则可以将cumsum
与shift
一起使用。(shift
是来自data.table
的函数;它与lag
相同)
在第一步中使用@Hugh方法,然后得到最终结果:
test[, cycle := cumsum(level > shift(level, fill = first(level))), by = "id"]
x <- test[, .(start = min(time),
recharge = max(time),
diffcharge = max(level) - min(level)),
by = .(id, cycle)]
x[, difftime := as.numeric(recharge - start)]
x[, rate := diffcharge / difftime]
x
# id cycle start recharge diffcharge difftime rate
# 1: 1 0 2017-12-25 14:10:03 2017-12-25 16:00:04 21 110.01283 0.1908868
# 2: 1 1 2017-12-25 16:10:04 2017-12-25 17:20:03 16 69.98285 0.2286274
# 3: 2 0 2017-12-25 17:30:03 2017-12-25 19:00:03 89 89.99613 0.9889314
# 4: 2 1 2017-12-25 19:10:04 2017-12-25 20:10:03 13 59.99771 0.2166749
# 5: 2 2 2017-12-25 20:20:04 2017-12-25 20:40:03 3 19.99584 0.1500312
test[,cycle:=cumsum(level>shift(level,fill=first(level)),by=“id”]
x在第一步使用@Hugh方法,然后得到最终结果:
test[, cycle := cumsum(level > shift(level, fill = first(level))), by = "id"]
x <- test[, .(start = min(time),
recharge = max(time),
diffcharge = max(level) - min(level)),
by = .(id, cycle)]
x[, difftime := as.numeric(recharge - start)]
x[, rate := diffcharge / difftime]
x
# id cycle start recharge diffcharge difftime rate
# 1: 1 0 2017-12-25 14:10:03 2017-12-25 16:00:04 21 110.01283 0.1908868
# 2: 1 1 2017-12-25 16:10:04 2017-12-25 17:20:03 16 69.98285 0.2286274
# 3: 2 0 2017-12-25 17:30:03 2017-12-25 19:00:03 89 89.99613 0.9889314
# 4: 2 1 2017-12-25 19:10:04 2017-12-25 20:10:03 13 59.99771 0.2166749
# 5: 2 2 2017-12-25 20:20:04 2017-12-25 20:40:03 3 19.99584 0.1500312
test[,cycle:=cumsum(level>shift(level,fill=first(level)),by=“id”]
x假设您从csv文件读取测试:
test<-read.csv("test.csv",stringsAsFactors = F)
test$DateTime<-paste(test$Date,test$time,by=" ")
test$Charge<-FALSE
test$Charge[1:((nrow(test)-1))]<-diff(test$level)>0
start=test[which(test$Charge)+1,]$DateTime
start<-c(test$DateTime[1],start)
start<-dmy_hms(start)
recharge<-filter(test,Charge)$DateTime
recharge<-c(recharge,tail(test$DateTime,1))
recharge<-dmy_hms(recharge)
difftime=recharge-start
startLevel=test[which(test$Charge)+1,]$level
startLevel=c(test$level[1],startLevel)
endLevel=filter(test,Charge)$level
endLevel=c(endLevel,tail(test$level,1))
diffcharge=startLevel-endLevel
rate=diffcharge/as.numeric(difftime)
id=filter(test,Charge)$id
id=c(id,tail(test$id,1))
outcome=data.frame(id=id,start=start,recharge=recharge,difftime=difftime,diffcharge=diffcharge,rate=rate)
test假设您从csv文件读取测试:
test<-read.csv("test.csv",stringsAsFactors = F)
test$DateTime<-paste(test$Date,test$time,by=" ")
test$Charge<-FALSE
test$Charge[1:((nrow(test)-1))]<-diff(test$level)>0
start=test[which(test$Charge)+1,]$DateTime
start<-c(test$DateTime[1],start)
start<-dmy_hms(start)
recharge<-filter(test,Charge)$DateTime
recharge<-c(recharge,tail(test$DateTime,1))
recharge<-dmy_hms(recharge)
difftime=recharge-start
startLevel=test[which(test$Charge)+1,]$level
startLevel=c(test$level[1],startLevel)
endLevel=filter(test,Charge)$level
endLevel=c(endLevel,tail(test$level,1))
diffcharge=startLevel-endLevel
rate=diffcharge/as.numeric(difftime)
id=filter(test,Charge)$id
id=c(id,tail(test$id,1))
outcome=data.frame(id=id,start=start,recharge=recharge,difftime=difftime,diffcharge=diffcharge,rate=rate)
test谢谢,但这如何考虑手机的id
?例如,一个id
可能在80级结束,然后下一个id
可能从79级开始,但这仍然会被视为同一个循环,即使这是不正确的,这有意义吗?是的。在这种情况下,fill=first(level)
如何工作?请尝试省略fill
参数;cycle
列将是一列NA
s。因此,您需要为每个组提供一个合理的首值。谢谢,但这如何考虑手机的id
?例如,一个id
可能在80级结束,然后下一个id
可能从79级开始,但这仍然会被视为同一个循环,即使这是不正确的,这有意义吗?是的。在这种情况下,fill=first(level)
如何工作?请尝试省略fill
参数;cycle
列将是一列NA
s。因此,您需要为每个组提供一个合理的第一个值。