我有一个带有变量值的数据框(以NAs开头)和该值有效的时间。我想确定最近该值是否快速变化,其中“快速”定义为在过去一分钟内减少/增加超过5
例如,这是我的数据框
example <- data.frame(variable = c('a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b'),
time = c(Sys.time(), Sys.time() + 5, Sys.time() + 15, Sys.time() + 34, Sys.time() + 151, Sys.time(), Sys.time() + 1, Sys.time() + 5, Sys.time() + 77, Sys.time() + 79, Sys.time() + 102, Sys.time() + 110, Sys.time() + 145),
value = c(NA, 3, 6, 2, 8, NA, 15, 11, 8, 6, 4, 0, 3))
您可以使用代码
显示数据library(ggplot2)
ggplot(example, aes(x = time, y = value, by = variable)) + geom_step()
我想添加一个布尔列,显示该值在过去一分钟内是否移动了5次以上,因此最终得到以下结果:
variable time value fast_move
1 a 2017-11-06 15:59:10 NA FALSE
2 a 2017-11-06 15:59:15 3 FALSE
3 a 2017-11-06 15:59:25 6 FALSE
4 a 2017-11-06 15:59:44 2 FALSE
5 a 2017-11-06 16:01:41 8 TRUE
6 b 2017-11-06 15:59:10 NA FALSE
7 b 2017-11-06 15:59:11 15 FALSE
8 b 2017-11-06 15:59:15 11 FALSE
9 b 2017-11-06 16:00:27 8 FALSE
10 b 2017-11-06 16:00:29 6 FALSE
11 b 2017-11-06 16:00:52 4 TRUE
12 b 2017-11-06 16:01:00 0 TRUE
13 b 2017-11-06 16:01:35 3 FALSE
第5行是TRUE
,因为它一次性从2变为8(变化6)。
第9行是FALSE
,因为虽然它已从15移到8,但它在超过60秒内完成了此操作
第11行是TRUE
,因为它在26秒内从11变为4(16:00:26为11,16:00:52为4)。同样,第12行是TRUE
实际的数据帧超过1,000,000行,有很多变量,所以任何特别慢的东西都可能有问题!
任何帮助将不胜感激
修改
回答useR对我到目前为止所做的评论......
我目前已经找到了之前60秒的值,并计算了差异。如果是> 5将fast_move设置为TRUE。使用以下代码执行此操作
isFastMove <- function(data){
library(data.table)
data <- data %>%
unique() %>%
data.table
prevData <- mutate(data, time = time - 60) %>%
select(-value) %>%
data.table
setkeyv(data, c('variable', 'time'))
setkeyv(prevData, c('variable', 'time'))
prevData <- data[prevData, roll = T, rollends = T] %>%
mutate(time = time + 60) %>%
rename(previous_value = value)
data <- merge(data, prevData, by = c('variable', 'time')) %>%
mutate(fast_move = !is.na(previous_value) & abs(value - previous_value) > 5)
return(data)
}
然而,这并不总是有效,例如,如果值为3,则降至1并立即增加到7.这将是一个快速移动但是当我比较30秒前它是3,并且不会'被归类为快速行动。
答案 0 :(得分:1)
对一个变量使用 Rcpp 函数应该很快:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
LogicalVector fastMove(const NumericVector& time,
const NumericVector& value,
double nsec = 60,
double nval = 5) {
int n = time.size();
LogicalVector fast_move(n);
int i, j;
double tmin, vmin, vmax;
for (i = n - 1; i > 0; i--) {
tmin = time[i] - nsec;
vmin = value[i] - nval;
vmax = value[i] + nval;
for (j = i - 1; j > 0; j--) {
if (time[j + 1] - 1 < tmin) break;
if (value[j] < vmin || value[j] > vmax) {
fast_move[i] = true;
break;
}
}
}
return fast_move;
}
要将此功能应用于每个变量,请使用 dplyr :
library(dplyr)
example %>%
group_by(variable) %>%
mutate(fast_move = fastMove(time, value))