2016-10-05 3 views
1

Как бы вы подмножали временные ряды data.frame на основе времени и порогового значения?r - Подмножество временных рядов data.frame на основе времени и порога

У меня есть эти данные:

year <- seq(2000, 2009, 1) 
v1 <- sample(1:10, 10, replace=T) 
df <- data.frame(year, v1) 

Это выглядит следующим образом:

> df 
    year v1 
1 2000 9 
2 2001 4 
3 2002 5 
4 2003 4 
5 2004 5 
6 2005 3 
7 2006 3 
8 2007 3 
9 2008 9 
10 2009 6 

Я хочу подмножество данных по группам последовательных лет, для которых суммарный балл по v1 превышает значение 10.

В этом примере данные первого подмножества должны содержать наблюдения за 2000 годом & 2001. Второе подмножество shou ld проводят наблюдения за 2002, 2003 и 2004 годы.

Реальные данные имеют около 8 миллионов наблюдений, охватывающих 120 лет.

+1

Пожалуйста, используйте 'set.seed' при создании примеров с использованием' sample' –

ответ

2

Вы можете реализовать настроенное cumsum используя Reduce функцию, сбросить сумму, если сумма превышает 10, и в то же время увеличиваем счетчик в качестве групповой переменной:

library(data.table) 
transpose(Reduce(function(x, y) if(x[1] > 10) c(y, x[2]+1) else c(x[1] + y, x[2]), 
       init = c(0, 1), df$v1, accumulate = T))[[2]][-1] 

# here the init parameter will take two parameters, the first one keep track of the cumsum, 
# and the second one serves as a group variable, when the sum exceeds 10, reset the sum to 
# zero and increase the group variable by one 

# [1] 1 1 2 2 2 3 3 3 3 4 

Это занимает около 20 секунд, чтобы запустить более 10 миллионов наблюдение вектора:

v = sample(1:10, 10000000, replace = T) 
system.time(transpose(Reduce(function(x, y) if(x[1] > 10) c(y, x[2]+1) else c(x[1] + y, x[2]), init = c(0, 1), v, accumulate = T))[[2]]) 

# user system elapsed 
# 19.509 0.552 20.081 
+0

Спасибо за ваш ввод. Это отлично работает и является тем видом ответа, который я ищу. Когда я использую этот код, на выходе есть еще 1 наблюдение, чем 'df'. Как вы думаете, откуда это взялось? –

+1

Ahh, приятно поймать. Он исходит из начального параметра, переданного функции «Уменьшить». Вы можете исключить его с помощью 'transpose (Reduce (function (x, y) if (x [1]> 10) c (y, x [2] +1) else c (x [1] + y, x [2]), init = c (0, 1), df $ v1, accumulate = T)) [[2]] [- 1] '. – Psidom