根据条件计算平均值

时间:2017-07-20 05:53:21

标签: r dataframe

以下是我的数据框,

    Row_ID  A      B  
       1   0       0  
       2   0       0  
       3   0       0  
       4   0       1  
       5   0       1  
       6   0       1  
       7  62.75    0  
       8  100      0  
       9  100      0 
      10  100     -1 
      11  100     -1  
      12  100     -1  
      13  100     -1   
      14  87.625  -1  
      15   0       0  
      16   0       0  
      17   0       1   
      18   0       1  
      19   10      1    
      20   13.43   1
      21   67.31   0  
      22   86.5    0
      23   99      0  
      24   99      0  
      25   99      0 

我需要在以下条件下连续5行计算A的平均值  1 and -1中的值B是两个过渡状态。

a A的平均值基于B中的值。

b 要考虑进行平均计算的A数据点从B转换结束的最后一个数据点开始。 (示例:B中的转换在Row_ID = 6结束,因此,A的行号为7,8,9,10和11必须考虑计算平均值)。

c 参考上面的示例,虽然B的第10行和第11行的值发生了变化,但A中的相应行应考虑进行计算平均值是因为这些值是在前一次迭代中的平均计算中考虑的。

是否有任何解决方法代码没有使用 embed() 函数,因为我的数据有大约900K值,而 embed() 创建矩阵,内存使用量不会是最佳的。

预期输出

    Row_ID  A      B   Avg  
       1   0       0     0  
       2   0       0     0  
       3   0       0     0  
       4   0       1     0  
       5   0       1     0  
       6   0       1     0  
       7  62.75    0     92.55  
       8  100      0     92.55  
       9  100      0     92.55 
      10  100     -1     92.55 
      11  100     -1     92.55  
      12  100     -1     0  
      13  100     -1     0   
      14  87.625  -1     0  
      15   0       0     2  
      16   0       0     2  
      17   0       1     2   
      18   0       1     2  
      19   10      1     2    
      20   13.43   1     0
      21   67.31   0     90.16  
      22   86.5    0     90.16
      23   99      0     90.16  
      24   99      0     90.16  
      25   99      0     90.16

1 个答案:

答案 0 :(得分:2)

我们可以使用data.table

library(data.table)
setDT(df1)[, Avg := mean(A)*(.N>4), cumsum(c(TRUE,  diff(abs(B)!=1)==1))]
df1
#    Row_ID  A  B  Avg
# 1:      1  0  0  0.0
# 2:      2  5  1  0.0
# 3:      3  6  1  0.0
# 4:      4  8  1  0.0
# 5:      5  9  0 10.2
# 6:      6  8  0 10.2
# 7:      7 15 -1 10.2
# 8:      8 17 -1 10.2
# 9:      9  2 -1 10.2
#10:     10  6  0  0.0
#11:     11  9  0  0.0
#12:     12  8 -1  0.0
#13:     13  5 -1  0.0
#14:     14  2  0  6.4
#15:     15  9  0  6.4
#16:     16  2  1  6.4
#17:     17  9  1  6.4
#18:     18 10  1  6.4

@thelatemail的方法

setDT(df1)[,  Avg := mean(A) *(.N > 4) , (rleid(B) + 1) %/% 2]

更新

基于新的例子,也许这有助于

setDT(df2)[, Avg := c(rep(mean(head(A, 5)), 5), rep(0, .N-5)), 
        cumsum(c(TRUE,  diff(abs(B)!=1)==1))]
df2
#    Row_ID       A  B    Avg
# 1:      1   0.000  0  0.000
# 2:      2   0.000  0  0.000
# 3:      3   0.000  0  0.000
# 4:      4   0.000  1  0.000
# 5:      5   0.000  1  0.000
# 6:      6   0.000  1  0.000
# 7:      7  62.750  0 92.550
# 8:      8 100.000  0 92.550
# 9:      9 100.000  0 92.550
#10:     10 100.000 -1 92.550
#11:     11 100.000 -1 92.550
#12:     12 100.000 -1  0.000
#13:     13 100.000 -1  0.000
#14:     14  87.625 -1  0.000
#15:     15   0.000  0  2.000
#16:     16   0.000  0  2.000
#17:     17   0.000  1  2.000
#18:     18   0.000  1  2.000
#19:     19  10.000  1  2.000
#20:     20  13.430  1  0.000
#21:     21  67.310  0 90.162
#22:     22  86.500  0 90.162
#23:     23  99.000  0 90.162
#24:     24  99.000  0 90.162
#25:     25  99.000  0 90.162