【问题标题】:Mean function R with missing values, loop on 5 rows具有缺失值的平均函数 R,循环 5 行
【发布时间】:2021-12-12 21:55:19
【问题描述】:

我想计算 df 中每 5 行的平均值。这是我的 df :

Time value
03/06/2021 06:15:00 NA
03/06/2021 06:16:00 NA
03/06/2021 06:17:00 20
03/06/2021 06:18:00 22
03/06/2021 06:19:00 25
03/06/2021 06:20:00 NA
03/06/2021 06:21:00 31
03/06/2021 06:22:00 23
03/06/2021 06:23:00 19
03/06/2021 06:24:00 25
03/06/2021 06:25:00 34
03/06/2021 06:26:00 42
03/06/2021 06:27:00 NA
03/06/2021 06:28:00 19
03/06/2021 06:29:00 17
03/06/2021 06:30:00 25

我已经有一个循环,可以很好地计算每 5 行包的平均值。我的问题在于我的“平均功能”。
问题是:
-如果我把 na.rm = FALSE, mean = NA 只要在 5 个值的包中有 NA。
- 如果我将 na.rm = TRUE 放在 mean 函数中,结果会给我平均值,这些平均值被转移为 5 个值。
我希望 NA 不会干扰平均值,并且当有 NA 时在包含 5 个值的包中,仅对 4 个值进行平均。
我怎样才能做到这一点?感谢您的帮助!

【问题讨论】:

    标签: r time mean na


    【解决方案1】:

    您可以通过引入一个虚拟变量来解决您的问题,该变量将您的观测值分成五个一组,然后计算组内的平均值。这是基于 tidyverse 的 MWE,它假设您的数据位于名为 df 的 data.frame 中。

    library(tidyverse)
    
    df %>% 
       mutate(Group= 1 + floor((row_number()-1) / 5)) %>% 
       group_by(Group) %>% 
       summarise(Mean=mean(value, na.rm=TRUE), .groups="drop")
    # A tibble: 4 × 2
      Group  Mean
      <dbl> <dbl>
    1     1  22.3
    2     2  24.5
    3     3  28  
    4     4  25  
    

    【讨论】:

      【解决方案2】:

      基于purrr::map_dfr的解决方案:

      library(purrr)
      
      df <- data.frame(
        stringsAsFactors = FALSE,
                          time = c("03/06/2021 06:15:00","03/06/2021 06:16:00",
                                   "03/06/2021 06:17:00",
                                   "03/06/2021 06:18:00","03/06/2021 06:19:00",
                                   "03/06/2021 06:20:00","03/06/2021 06:21:00",
                                   "03/06/2021 06:22:00","03/06/2021 06:23:00",
                                   "03/06/2021 06:24:00","03/06/2021 06:25:00",
                                   "03/06/2021 06:26:00",
                                   "03/06/2021 06:27:00","03/06/2021 06:28:00",
                                   "03/06/2021 06:29:00","03/06/2021 06:30:00"),
                         value = c(NA,NA,20L,22L,
                                   25L,NA,31L,23L,19L,25L,34L,42L,NA,19L,17L,
                                   25L)
            )
      
      map_dfr(1:(nrow(df)-5),
              ~ data.frame(Group =.x, Mean = mean(df$value[.x:(.x+5)],na.rm=T)))
      #>    Group     Mean
      #> 1      1 22.33333
      #> 2      2 24.50000
      #> 3      3 24.20000
      #> 4      4 24.00000
      #> 5      5 24.60000
      #> 6      6 26.40000
      #> 7      7 29.00000
      #> 8      8 28.60000
      #> 9      9 27.80000
      #> 10    10 27.40000
      #> 11    11 27.40000
      

      【讨论】:

        【解决方案3】:

        如果你想每 5 分钟取一次平均值,你可以使用lubridate 的函数floor_date/ceiling_date 来取整时间。

        library(dplyr)
        library(lubridate)
        
        df %>%
          mutate(time = mdy_hms(time), 
                 time = floor_date(time, '5 mins')) %>%
          group_by(time) %>%
          summarise(value = mean(value, na.rm = TRUE))
        
        #  time                value
        #  <dttm>              <dbl>
        #1 2021-03-06 06:15:00  22.3
        #2 2021-03-06 06:20:00  24.5
        #3 2021-03-06 06:25:00  28  
        #4 2021-03-06 06:30:00  25  
        

        【讨论】:

        • 您好,我无法根据您的问题调整您的解决方案,我还有另一个限制,即我必须在某些时间戳上进行这些平均值,但根本不需要。我的代码看起来像这样,其中 num = 行数,我必须在有问题的行之前平均 5 个值。 'for (i in num) { df[i,"value"]
        猜你喜欢
        • 2017-01-03
        • 1970-01-01
        • 2016-04-16
        • 1970-01-01
        • 2016-11-19
        • 1970-01-01
        • 2019-08-24
        • 1970-01-01
        • 2019-12-15
        相关资源
        最近更新 更多