本文介绍了前一组与另一列在同一位置的平均值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些数据,我将mdo值除以上一组中mdo实例的计数.

I have some data and I am dividing the mdo value by the count number of mdo instances in the previous group.

我也在计算sog平均数.

I am calculating the sog avg also.

但是我想计算发生在与结果(mdo/count)值相同的实例上的sog avg.

But I want to calculate the sog avg that takes place to the same instances as the result (mdo/count) value.

library(dplyr)
library(lubridate)
library(purrr)

df <- tibble(mydate = as.Date(c("2019-05-11 23:01:00", "2019-05-11 23:02:00", "2019-05-11 23:03:00", "2019-05-11 23:04:00",
                                "2019-05-12 23:05:00", "2019-05-12 23:06:00", "2019-05-12 23:07:00", "2019-05-12 23:08:00",
                                "2019-05-13 23:09:00", "2019-05-13 23:10:00", "2019-05-13 23:11:00", "2019-05-13 23:12:00",
                                "2019-05-14 23:13:00", "2019-05-14 23:14:00", "2019-05-14 23:15:00", "2019-05-14 23:16:00",
                                "2019-05-15 23:17:00", "2019-05-15 23:18:00", "2019-05-15 23:19:00", "2019-05-15 23:20:00",
                                "2019-05-15 23:21:00", "2019-05-15 23:22:00", "2019-05-15 23:23:00", "2019-05-15 23:24:00",
                                "2019-05-15 23:25:00")),
             mdo = c(1500, 1500, 1500, 1500,
                     1500, 1500, NA, 0,
                     0, 0, 900, 900, NA, NA, 1100, 1100,
                     1100, 200, 200, 200,200,
                     1100, 1100, 1100, 0
             ),
             sog = c(12, 12, 12, 11, 10,9,
                     2,8.8, 8.7, 7.8, 11, 11, 12, 11,
                     9.54, 9.8, 10.4,4, 4, 4.5, 3.6,
                     7, 8, 9, 0))

df1 <- df %>%
    mutate(grp = data.table::rleid(mdo))

df1 <- df1 %>%
    #Keep only non-NA value
    filter(!is.na(mdo)) %>%
    #count occurence of each grp
    count(grp, name = 'count') %>%
    #Shift the count to the previous group
    mutate(count = lag(count)) %>%
    #Join with the original data
    right_join(df1, by = 'grp') %>%
    arrange(grp)

group_mdo <- df1 %>%
    select(grp, mdo) %>%
    unique() %>%
    mutate(prev_mdo = lag(mdo, na.rm=TRUE)) %>%
    select(-mdo) %>%
    tidyr::fill(prev_mdo, .direction = "down")


df1 <- df1 %>%
    left_join(group_mdo, by = "grp") %>%
    mutate(result = ifelse(prev_mdo != 0, mdo / count, 0)) %>%
    mutate(sog_avg = ifelse(prev_mdo != 0, map_dbl(.x = grp - 1, ~ mean(sog[grp == .x], na.rm=TRUE), na.rm=TRUE), NA)) 

现在的结果是:

grp count    mydate       mdo   sog prev_mdo result sog_avg
 1    NA    2019-05-11   1500    12    NA     NA     NA  
 1    NA    2019-05-11   1500    12    NA     NA     NA  
 1    NA    2019-05-11   1500    12    NA     NA     NA  
 1    NA    2019-05-11   1500    11    NA     NA     NA  
 1    NA    2019-05-12   1500    10    NA     NA     NA  
 1    NA    2019-05-12   1500     9    NA     NA     NA  
 2    NA    2019-05-12     NA     2    1500   NA     11  
 3     6    2019-05-12     0     8.8   1500   0      2  
 3     6    2019-05-13     0     8.7   1500   0      2  
 3     6    2019-05-13     0     7.8   1500   0      2  
 4     3    2019-05-13   900     11    0      0      NA  
 4     3    2019-05-13   900     11    0      0      NA  
 5    NA    2019-05-14     NA    12    900    NA     11  
 5    NA    2019-05-14     NA    11    900    NA     11  
 6     2    2019-05-14   1100    9.54  900   550    11.5
 6     2    2019-05-14   1100    9.8   900   550    11.5
 6     2    2019-05-15   1100    10.4  900   550    11.5
 7     3    2019-05-15   200     4      1100  66.7   9.91
 7     3    2019-05-15   200     4     1100   66.7   9.91
 7     3    2019-05-15   200     4.5   1100   66.7   9.91
 7     3    2019-05-15   200     3.6   1100   66.7   9.91
 8     4    2019-05-15   1100    7     200    275    4.03
 8     4    2019-05-15   1100    8     200    275    4.03
 8     4    2019-05-15   1100    9     200    275    4.03
 9     3    2019-05-15     0     0     1100     0      8   

我想要的结果:

  grp count    mydate       mdo   sog prev_mdo result sog_avg
     1    NA    2019-05-11   1500    12    NA     NA     NA  
     1    NA    2019-05-11   1500    12    NA     NA     NA  
     1    NA    2019-05-11   1500    12    NA     NA     NA  
     1    NA    2019-05-11   1500    11    NA     NA     NA  
     1    NA    2019-05-12   1500    10    NA     NA     NA  
     1    NA    2019-05-12   1500     9    NA     NA     NA  
     2    NA    2019-05-12     NA     2    1500   NA     NA  
     3     6    2019-05-12     0     8.8   1500   0      0  
     3     6    2019-05-13     0     8.7   1500   0      0  
     3     6    2019-05-13     0     7.8   1500   0      0  
     4     3    2019-05-13   900     11    0      0      0  
     4     3    2019-05-13   900     11    0      0      0  
     5    NA    2019-05-14     NA    12    900    NA     NA  
     5    NA    2019-05-14     NA    11    900    NA     NA  
     6     2    2019-05-14   1100    9.54  900   550    11
     6     2    2019-05-14   1100    9.8   900   550    11
     6     2    2019-05-15   1100    10.4  900   550    11
     7     3    2019-05-15   200     4     1100  66.7   9.91
     7     3    2019-05-15   200     4     1100   66.7   9.91
     7     3    2019-05-15   200     4.5   1100   66.7   9.91
     7     3    2019-05-15   200     3.6   1100   66.7   9.91
     8     4    2019-05-15   1100    7     200    275    4.03
     8     4    2019-05-15   1100    8     200    275    4.03
     8     4    2019-05-15   1100    9     200    275    4.03
     9     3    2019-05-15     0     0     1100     0      0   

结果为零时,sog_avg应该为零,结果为na时,sog avg应该为na.

Where result is zero, sog_avg should be zero, where result is na, sog avg should be na.

如果要使用先前的组计数来计算结果,则应使用其先前的值来计算sog avg.

And where result is being computed by using the previous group counts, sog avg should be computed with it's previous values.

例如,

mdo = 1100,结果为550,因为前一个非空组中的计数为2(mdo值为900).

mdo = 1100 , result is 550 because counts in previous non null group are 2 (mdo value 900).

1100/2 = 550.此时,sog avg应该为(11 + 11)/2 = 11,因为前一个非空组中的计数为2.

1100 / 2 = 550 . At this point sog avg should be (11 + 11) / 2 = 11 because counts were 2 in the previous non null group.

推荐答案

这是一个 data.table 方法.它广泛使用通过使用基本 table tapply 进行分组的想法,然后使这些结果滞后.请注意,如果 mdo 在整个组中不是恒定的,则此答案将失败.

Here is a data.table approach. It extensively uses the idea of making groups by using base table or tapply and then lags those results. Note, this answer would fail if mdo is not constant throughout a group.

library(data.table)

dt = as.data.table(df)

dt[, grp := rleid(mdo)]

dt[!is.na(mdo), 
   count := {
      cnt = table(grp)
      rep(shift(cnt), cnt)
      }
   ]

setcolorder(dt, c("grp", "count", "mydate", "mdo", "sog"))

dt[,
   prev_mdo := {
     ord = table(grp)
     nafill(rep(shift(mdo[cumsum(ord)]), ord), "locf")
     }
   ]


dt[, result := fifelse(prev_mdo != 0L, mdo / count, 0)]

dt[!is.na(result),
   sog_avg := {
     mn = tapply(sog, grp, mean)
     rep(shift(mn), table(grp))
   }]

dt[result == 0 | is.na(result), sog_avg := result]
dt
#>     grp count     mydate  mdo   sog prev_mdo    result   sog_avg
#>  1:   1    NA 2019-05-11 1500 12.00       NA        NA        NA
#>  2:   1    NA 2019-05-11 1500 12.00       NA        NA        NA
#>  3:   1    NA 2019-05-11 1500 12.00       NA        NA        NA
#>  4:   1    NA 2019-05-11 1500 11.00       NA        NA        NA
#>  5:   1    NA 2019-05-12 1500 10.00       NA        NA        NA
#>  6:   1    NA 2019-05-12 1500  9.00       NA        NA        NA
#>  7:   2    NA 2019-05-12   NA  2.00     1500        NA        NA
#>  8:   3     6 2019-05-12    0  8.80     1500   0.00000  0.000000
#>  9:   3     6 2019-05-13    0  8.70     1500   0.00000  0.000000
#> 10:   3     6 2019-05-13    0  7.80     1500   0.00000  0.000000
#> 11:   4     3 2019-05-13  900 11.00        0   0.00000  0.000000
#> 12:   4     3 2019-05-13  900 11.00        0   0.00000  0.000000
#> 13:   5    NA 2019-05-14   NA 12.00      900        NA        NA
#> 14:   5    NA 2019-05-14   NA 11.00      900        NA        NA
#> 15:   6     2 2019-05-14 1100  9.54      900 550.00000 11.000000
#> 16:   6     2 2019-05-14 1100  9.80      900 550.00000 11.000000
#> 17:   6     2 2019-05-15 1100 10.40      900 550.00000 11.000000
#> 18:   7     3 2019-05-15  200  4.00     1100  66.66667  9.913333
#> 19:   7     3 2019-05-15  200  4.00     1100  66.66667  9.913333
#> 20:   7     3 2019-05-15  200  4.50     1100  66.66667  9.913333
#> 21:   7     3 2019-05-15  200  3.60     1100  66.66667  9.913333
#> 22:   8     4 2019-05-15 1100  7.00      200 275.00000  4.025000
#> 23:   8     4 2019-05-15 1100  8.00      200 275.00000  4.025000
#> 24:   8     4 2019-05-15 1100  9.00      200 275.00000  4.025000
#> 25:   9     3 2019-05-15    0  0.00     1100   0.00000  0.000000
#>     grp count     mydate  mdo   sog prev_mdo    result   sog_avg

这篇关于前一组与另一列在同一位置的平均值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-25 09:32