计算cummean()和cumsd(),同时忽略NA值并填充NA

时间:2018-02-26 01:38:37

标签: r dataframe apply

我的目标是获取数据帧的暨平均值(和cumsd),同时忽略NA并填充前一个暨意味着:

DF:

var1   var2  var3   
x1     y1    z1    
x2     y2    z2
NA     NA    NA
x3     y3    z3    

cummean:

var1           var2         var3   
 x1/1          y1/1          z1/1    
(x1+x2)/2     (y1+y2)/2     (z1+z2)/2
(x1+x2)/2     (y1+y2)/2     (z1+z2)/2
(x1+x2+x3)/3  (y1+y2+y3)/3  (z1+z2+z3)/3 

因此对于df具有NA的第3行,我希望新矩阵包含上面一行中的暨平均值(分子不应该增加)。

到目前为止,我正在使用它来计算暨平均值(我知道在某个地方因为我使用了for循环而不是来自申请家族的东西而被杀死了)

for(i in names(df){
  df[i][!is.na(df[i])] <- GMCM:::cummean(df[i][!is.na(df[i])])
}

我也试过这个:

setDT(posRegimeReturns)    
cols<-colnames((posRegimeReturns))    
posRegimeReturns[, (cols) := lapply(.SD,  cummean) , .SD = cols]

但是这两个都让NAs空了。

注意:此问题与此帖Calculate cumsum() while ignoring NA values类似 但与那里的解决方案不同,我不想离开NAs,而是填充与上面不是NA的最后一行相同的值。

2 个答案:

答案 0 :(得分:2)

您可能希望使用definition方差来计算此

library(data.table)
dt <- data.table(V1=c(1,2,NA,3), V2=c(1,2,NA,3), V3=c(1,2,NA,3))

cols <- copy(names(dt))

#means
dt[ , paste0("mean_",cols) := lapply(.SD, function(x) {
    #get the num of non-NA observations
    lens <- cumsum(!is.na(x))

    #set NA to 0 before doing cumulative sum
    x[is.na(x)] <- 0
    cumsum(x) / lens
}), .SDcols=cols]

#sd
dt[ , paste0("sd_",cols) := lapply(.SD, function(x) {
    lens <- cumsum(!is.na(x))
    x[is.na(x)] <- 0

    #use defn of variance mean of sum of squares minus square of means and also n-1 in denominator
    sqrt(lens/(lens-1) * (cumsum(x^2)/lens - (cumsum(x) / lens)^2))
}), .SDcols=cols]

答案 1 :(得分:2)

使用data table。特别是:

 library(data.table)
 DT <- data.table(z = sample(N),idx=1:N,key="idx")

     z  idx
 1:  4   1
 2: 10   2
 3:  9   3
 4:  6   4
 5:  1   5
 6:  8   6
 7:  3   7
 8:  7   8
 9:  5   9  
10:  2  10

我们现在使用-apply函数和data.table

DT[,cummean:=sapply(seq(from=1,to=nrow(DT)) ,function(iii) mean(DT$z[1:iii],na.rm = TRUE))]
DT[,cumsd:=sapply(seq(from=1,to=nrow(DT)) ,function(iii) sd(DT$z[1:iii],na.rm = TRUE))]

导致:

             z idx  cummean    cumsd
         1:  4   1 4.000000       NA
         2: 10   2 7.000000 4.242641
         3:  9   3 7.666667 3.214550
         4:  6   4 7.250000 2.753785
         5:  1   5 6.000000 3.674235
         6:  8   6 6.333333 3.386247
         7:  3   7 5.857143 3.338092
         8:  7   8 6.000000 3.116775
         9:  5   9 5.888889 2.934469
        10:  2  10 5.500000 3.027650