2016-08-02 3 views
1

Я должен решить эту конкретную проблему в R. У меня есть большой список, содержащие столбцы и строки в следующем формате:Получить сумму определенного числа следующих строк в R

Day_and_Time Rain1_mm/min Rain2_mm/min 
    01.12.10 18:01  0    0 
    .............. ....   ... 
    02.12.10 01:00 0.03    0    
    02.12.10 01:01 0.03    0   
    02.12.10 01:02 0.01    0   
    02.12.10 01:03 0.05    0   
    02.12.10 01:04 0.03   0.1   
    02.12.10 01:05 0.04    0 
    .............. ....   ... 
    02.12.10 18:00  0    0 

То, что я хочу do - написать функцию, которая суммирует шесть следующих строк и возвращает результат как новую строку. Это означает, что в конце у меня есть новый список, который выглядит следующим образом:

Day_and_Time   Rain1_mm/5min Rain2_mm/5min 
    ..............   ....   ... 
    02.12.10 01:05   0.19   0.1   
    02.12.10 01:10   ....   ... 
    ..............   ....   ... 

Возможно ли это? Цель состоит в том, чтобы преобразовать блок [мм/мин] из первого и второго столбцов в [мм/5 мин].

спасибо!

+0

У вас есть строка за каждую минуту? – aichao

+0

Да, с 01.12.10 18:01 до 02.12.10 18:00. Так что 23 часа, всего 59 минут! – Frosi

+1

Определенно возможно. Было бы неплохо, если бы вы дали некоторые данные для создания решений по использованию dput(). – snoram

ответ

0

Предполагая, что вы читаете данные в файле .csv в виде рамки df данных, один подход к вашей проблеме заключается в использовании rollapply из zoo пакета, чтобы дать вам качение суммы:

library(zoo) 

ind_keep <- seq(1,floor(nrow(df)/5)*5, by=5)      ## 1. 
out <- sapply(df[,-1], function(x) rollapply(x,6,sum))    ## 2. 
out <- data.frame(df[ind_keep+5,1],out[ind_keep,])     ## 3. 
colnames(out) <- c("Day_and_time","Rain1_mm/5min","Rain2_mm/5min") ## 4. 

Примечания:

  1. Здесь мы определяем индексы, соответствующие каждые 5 минут, где мы хотим сохранить текущую сумму в течение следующих 5 минут.
  2. Примените функцию скользящей суммы для каждого столбца.
    • Используйте sapply по всем столбцам df, который не является первым столбцом. Обратите внимание, что индексы столбцов, указанные в df[,-1], могут быть отрегулированы так, что вы обрабатываете только определенные столбцы.
    • Назначение: rollapply от zoo. Дополнительными аргументами являются ширина окна 5 и функция sum, так что это выполняет скользящую сумму. На данный момент out содержит скользящие суммы (более 5 минут) каждую минуту, но мы хотим, чтобы они каждые 5 минут. Поэтому
  3. Объединяет Day_and_time столбец из исходного df с out сохраняя только те столбцы, каждые 5 минут. Обратите внимание, что мы сохраняем последние Day_and_Time в каждом окне.
  4. Это просто переименовывает столбцы.

Использование данных MikeyMike, которая является

  Day_and_Time rain1 rain2 
1 2010-02-12 01:00:00 0.03 0.00 
2 2010-02-12 01:01:00 0.03 0.00 
3 2010-02-12 01:02:00 0.01 0.00 
4 2010-02-12 01:03:00 0.05 0.00 
5 2010-02-12 01:04:00 0.03 0.10 
6 2010-02-12 01:05:00 0.04 0.00 
7 2010-02-12 01:06:00 0.02 0.10 
8 2010-02-12 01:07:00 0.10 0.10 
9 2010-02-12 01:08:00 0.30 0.00 
10 2010-02-12 01:09:00 0.01 0.00 
11 2010-02-12 01:10:00 0.00 0.01 

это дает:

print(out) 
##   Day_and_time Rain1_mm/5min Rain2_mm/5min 
##1 2010-02-12 01:05:00   0.19   0.10 
##2 2010-02-12 01:10:00   0.47   0.21 

Обратите внимание на разницу в результате, этот подход предполагает, что вы хотите перекрывающихся окон, так как вы указали, что вы хотите суммируйте шесть чисел между интервалом [i,i+5] с интервалом 5 минут.


Продлить выше окно в закрытом интервале [i, i+nMin] в каждой nMin метки:

library(zoo) 
nMin <- 10  ## for example 10 minutes 
ind_keep <- seq(1, floor(nrow(df)/nMin)*nMin, by=nMin) 
out <- sapply(df[,-1], function(x) rollapply(x, nMin+1, sum)) 
out <- data.frame(df[ind_keep+nMin, 1],out[ind_keep,]) 
colnames(out) <- c("Day_and_time",paste0("Rain1_mm/",nMin,"min"),paste0("Rain2_mm/",nMin,"min")) 

Для этой работы данные должны иметь по крайней мере 2 * nMin + 1 строки

Надеется, что это помогает.

+0

Что мне нужно изменить, чтобы получить единицу mm/10min - так как суммировать 10 строк? Могу ли я написать [i, i + 10]? – Frosi

+0

@Frosi: просмотрите мое обновление. – aichao

0

Предполагая, что вы хотите группы быть 0 - 5 минут, 6 - 10 минут и т.д., это должно дать вам то, что вы ищете:

library(data.table) 
setDT(df)[,.(day_time = max(Day_and_Time), 
      rain1_sum=sum(rain1), 
      rain2_sum=sum(rain2)), 
      by=.(floor(as.numeric(Day_and_Time)/360))] 

    floor   day_time rain1_sum rain2_sum 
1: 3516540 2010-02-12 01:05:00  0.19  0.10 
2: 3516541 2010-02-12 01:10:00  0.43  0.21 

данных:

df <- structure(list(Day_and_Time = structure(c(1265954400, 1265954460, 
1265954520, 1265954580, 1265954640, 1265954700, 1265954760, 1265954820, 
1265954880, 1265954940, 1265955000), class = c("POSIXct", "POSIXt" 
), tzone = ""), rain1 = c(0.03, 0.03, 0.01, 0.05, 0.03, 0.04, 
0.02, 0.1, 0.3, 0.01, 0), rain2 = c(0, 0, 0, 0, 0.1, 0, 0.1, 
0.1, 0, 0, 0.01)), .Names = c("Day_and_Time", "rain1", "rain2" 
), row.names = c(NA, -11L), class = c("data.table", "data.frame" 
), .internal.selfref = <pointer: 0x0000000000240788>) 
Смежные вопросы