while循环使用data.table的条件

时间:2018-01-09 12:44:56

标签: r while-loop dplyr data.table

我是R中的循环新手,并且有一个相对简单的数据集来处理。我的示例数据集包含时间戳 - SELECT * FROM sales INNER JOIN partner on user_id = idpartner WHERE DATE((end_date) + 5) >= DATE(NOW()) ORDER BY end_date ASC LIMIT 0,50000,手机ID:time和手机电池电量: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

到目前为止,我已经尝试过简单地创建一个while循环来连接每个循环的级别,之后我可以使用以下代码获取min,max等,但这不会产生预期的输出。

> 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

有关如何使用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或简单的while循环的任何建议,我们将不胜感激。以下是示例数据:

dplyr

3 个答案:

答案 0 :(得分:2)

在第一步中使用@Hugh方法然后获得最终结果:

update_attributes

答案 1 :(得分:1)

如果testdata.table,您可以将cumsumshift一起使用。 (shift是来自data.table的函数;它与lag相同。)

test[, cycle := cumsum(level > shift(level, fill = first(level))), by = "id"]

答案 2 :(得分:1)

假设您从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)