【问题标题】:Calculating mean for every second value in a dataframe计算数据框中每秒值的平均值
【发布时间】:2015-09-10 10:41:12
【问题描述】:

我想按平均值聚合每两个单元格值,并在数据框的列中继续执行相同的过程。 更准确地说,请参阅以下数据框摘录:

    X         Y             Z
1   FRI 200101010000    -6.72
2   FRI 200101010030    -6.30
3   FRI 200101010100    -6.26
4   FRI 200101010130    -5.82
5   FRI 200101010200    -5.64
6   FRI 200101010230    -5.29
7   FRI 200101010300    -5.82
8   FRI 200101010330    -5.83
9   FRI 200101010400    -5.83
10  FRI 200101010430    -6.04
11  FRI 200101010500    -5.80
12  FRI 200101010530    -6.09

我想通过以 00 和 30 结尾的 Y 来计算每个 Z 的平均值,这意味着计算 #row 1+2、#row 3+4、#row 5+6 等的平均值...参见我在这里的期望:

    X         Y             Z
1   FRI 200101010100    -6.51
2   FRI 200101010200    -6.04
3   FRI 200101010300    -5.47
...

说明:Y 是时间:YYYYMMDDhhmm,我想将 30 分钟的测量值平均到 1 小时的测量值

【问题讨论】:

  • X 怎么样?它是否也应该出现在分组过程中?
  • 没有必要,因为所有行都有相同的 X
  • 您的数据是针对单个日期的?
  • 不,不是针对单个日期,而是针对单个测量站。说清楚:X=站名,Y=200101010000到201201010000的日期,Z=测值降水

标签: r dataframe aggregate mean


【解决方案1】:

这是一个可能的data.table 解决方案

library(data.table)
setDT(df)[, .(Y = Y[1L], Z = mean(Z)), by = .(X, indx = cumsum(substr(Y, 11, 12) == '00'))]
#      X indx            Y      Z
# 1: FRI    1 200101010000 -6.510
# 2: FRI    2 200101010100 -6.040
# 3: FRI    3 200101010200 -5.465
# 4: FRI    4 200101010300 -5.825
# 5: FRI    5 200101010400 -5.935
# 6: FRI    6 200101010500 -5.945

或者根据@akruns 评论,使用来自base 的aggregate(尽管输出可能需要一些额外的tweeking)

aggregate(Z ~ X + indx, transform(df, indx = cumsum(substr(Y, 11, 12) == '00')), mean)

【讨论】:

  • 使用aggregate aggregate(Z~ X + indx, transform(df, indx=cumsum(substr(Y,11,12)=='00')), FUN=mean)
【解决方案2】:

一个 base-R 解决方案,我首先将向量分成几部分并计算每个部分的平均值,这当然假设您指定的顺序始终成立。最后我将它们结合起来给出你的结果:

Z <- unlist(lapply(split(df$Z, ceiling(seq_along(df$Z) / 2)), mean))
new_df <- cbind(df[seq(1,nrow(df), 2), c("X", "Y")], Z)

输出:

     X            Y      Z
1  FRI 200101010000 -6.510
3  FRI 200101010100 -6.040
5  FRI 200101010200 -5.465
7  FRI 200101010300 -5.825
9  FRI 200101010400 -5.935
11 FRI 200101010500 -5.945

【讨论】:

    【解决方案3】:

    dplyr 版本

    library(dplyr)
    
    df$Y <- as.character(df$Y)
    
    means <- df %>%
            group_by(hour = substr(Y, start = 1, stop=10)) %>% summarise(Z = mean(Z))
    
    > means
    Source: local data frame [6 x 2]
    
            hour      Z
    1 2001010100 -6.510
    2 2001010101 -6.040
    3 2001010102 -5.465
    4 2001010103 -5.825
    5 2001010104 -5.935
    6 2001010105 -5.945
    

    按 Y 变量对数据进行分组,不包括最后两位数。

    【讨论】:

    • 对不起。忘记编辑了。它是数据框(df)。 X 不是必需的,因为该信息也在 date(Y) 变量中。
    • 无论哪种方式,您都不需要mutate,您可以按照df %&gt;% group_by(hour = substr(Y, start = 1, stop=10)) %&gt;% summarise(mean(Z))group_by 中一步完成。虽然我认为你应该添加结果,因为它与 OP 想要的并不完全相同
    • 谢谢。不知道那个。更新了答案
    【解决方案4】:

    虽然这并没有解决 OP,但如果您有 POSIXct 列,通常可以按秒聚合:

    library(lubridate)
    library(tidyverse)
    s <- seq(from=Sys.time(), length.out = 100, by=0.4)
    df  = data.frame(time=s,v=rnorm(length(s)))
    df %>% 
      group_by(time=floor_date(time, "1 second")) %>% 
      summarize(v=mean(v)) # you can put any other interval like 5 minute
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-02
      • 2021-12-16
      • 2017-12-04
      • 1970-01-01
      • 2021-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多