【问题标题】:Get the sum of a specific number of following rows in R获取R中特定数量的后续行的总和
【发布时间】:2016-08-02 20:47:33
【问题描述】:

我必须在 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

我想要做的是编写一个函数来总结六个后续行并将结果作为新行返回。这意味着最后我有一个新列表 - 例如如下所示:

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

可以这样做吗?目标是将单位 [mm/min] 从第一列和第二列转换为 [mm/5min]。

非常感谢!

【问题讨论】:

  • 你每分钟都有一行吗?
  • 是的,从 01.12.10 18:01 到 02.12.10 18:00。总共 23 小时,59 分钟!
  • 绝对有可能。如果您提供一些数据来生成使用 dput() 的解决方案,那就太好了。
  • 在不知道如何准确存储数据的情况下,不可能给出具体的答案。您可以查看针对类似问题的this question。

标签: r


【解决方案1】:

假设您将.csv 文件中的数据作为数据框df 读取,解决问题的一种方法是使用zoo 包中的rollapply 为您提供滚动总和:

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. 对每一列应用滚动求和函数。
    • 在不是第一列的df 的所有列上使用sapply。请注意,df[,-1] 中指定的列索引可以调整,以便您只处理某些列。
    • 要应用的函数是来自zoo 包的rollapply。附加参数是窗口的宽度5sum 函数,以便执行滚动求和。 此时,out 包含每分钟的滚动总和(超过 5 分钟),但我们只需要每 5 分钟一次。因此,
  3. 将原始df 中的Day_and_time 列与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

请注意结果的差异,此方法假定您想要重叠窗口,因为您指定要在每 5 分钟标记处对闭合区间 [i,i+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

希望这会有所帮助。

【讨论】:

  • 我必须更改什么才能获得单位 mm/10min - 那么如何总结 10 行?我可以写 [i,i+10] 吗?
【解决方案2】:

假设您希望组为 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>)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 2019-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-24
    相关资源
    最近更新 更多