查找值是否在数据框中快速移动

时间:2017-11-06 16:20:21

标签: r dataframe

我有一个带有变量值的数据框(以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,并且不会'被归类为快速行动。

1 个答案:

答案 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))