用分组方法替换NA

时间:2015-09-23 14:30:05

标签: r replace mean na

我有一个包含7,000个观察数据和196个变量的数据框,其中遍布有NA。我创建了一个函数来捕获数据框中每个数字变量的分组均值(187个数字变量,11个组)。如果观察是一个组的一部分,我现在正试图用适当的变量分组平均值替换NA。

基本上我想在框架中找到NA并用适当的组均值变量替换。

如果df[6501,174]是第7组& NA,然后用第7组变量174的平均值替换。

这是我正在使用的最小的数据框架,我关注效率。

历史时间序列数据如下:

str(HD_filtered)
Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   7032 obs. of  196 variables:
 $ Date: Factor w/ 87    levels "12/31/1993","03/31/1994",..: 1 2 2 2 2 2 2 2 2 2 ...
 $ V2: Factor w/ 1065 levels "","000361105",..: 246 183 312 31 80 87 132 124 121 211 ...
 $ V3: Factor w/ 744 levels "A S V","A V",..: 326 231 22 41 106 113 170 160 157 272 ...
 $ V4: Factor w/ 7 levels "BHS","BMU","CAN",..: 7 7 7 7 7 7 7 7 7 7 ...
 $ V5: Factor w/ 68 levels "I2",..: 48 16 17 28 11 10 38 28 11 13 ...
 $ V6: Factor w/ 1 level "C": 1 1 1 1 1 1 1 1 1 1 ...
 $ V7: Factor w/ 11 levels "S1",..: 7 4 9 1 6 8 8 1 6 6 ...
 $ V8: Factor w/ 146 levels "SI1",..: 8 77 57 51 16 91 93 49 31 22 ...
 $ V9: Factor w/ 1259 levels "","3HCKT","3RVTL",..: 261 23 294 26 82 95 111 1
 $ V10: num  0.429 7.4 5 7.75 12 ...
 $ V11: num  0.839 2.117 0.97 1.237 1.934 ...
 $ V12: num  NA -0.176 0.262 0.012 0.146 ...
 $ V12: num  NA NA NA NA NA NA NA NA NA NA ...
 $ V13: num  NA NA NA NA NA NA NA NA NA NA ...
 $ V196: num NA .045 .62 .034 NA NA NA .012 .03 NA

我使用dplyr创建了一个基于组(日期,V4,V5,V7,V8)计算V10:V196的均值的函数。

Summary_Stats_Function <- function(hd, cmn) {
  hd %>%
    group_by_(.dots = cmn) %>%
    summarise_each(funs(min, max, median, mean(., trim = 0.01, na.rm = TRUE), sd(., na.rm = TRUE)), V10:V196)
}

Universal_Summary_Stats_byV4 <- Summary_Stats_Function(HD_filtered, "V4")

提供摘要统计信息:

str(U_sector_summ_stats)
Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   11 obs. of  936 variables:
 $ V4: Factor w/ 11 levels "S1",..: 1 2 3 4 5 6 7 8 9 10 ...
 $ V10_min: num  0 0 0 0 0 0 0 0 0 0.5 ...
 $ V11_min: num  -1.0216 -1.8599 0.0501 -0.5723 NA ...
 $V196_min: num  -0.984 -0.815 -0.848 -0.981 -0.549 ...
 $V393_mean: num  4.087 2.716 5.116 2.813 0.589...
 $V588_mean: num  NA NA NA NA NA ...
 $V936_sd: num  107 103 120 103 129 ...

replace_with <- select(Universal_Summary_Stats_byV4, contains("_mean")

我正在试图弄清楚如何在replace_with中保留此函数的平均结果并将其重新放入HD_filtered,以便用适当的组均值替换NA。

我尝试使用'for'循环和'apply'功能但没有成功,我可能会对逻辑语法感到困惑?

1 个答案:

答案 0 :(得分:0)

可能不是一个优雅的解决方案,但这里是一个基础R解决方案,使用merge()数据帧的分组均值和嵌套for循环内的原始数据帧。

首先,由于您只需要资金支持,因此只需运行summarise_each(),即可获得V10_mean - V196_mean的输出。

Summary_Stats_Function <- function(hd, cmn) {
    hd %>%
    group_by_(.dots = cmn) %>%
    summarise_each(funs(mean(., trim = 0.01, na.rm = TRUE)), V10:V196)
}        

然后运行嵌套for循环,在组级调用上面的函数并在外循环中合并数据框:

# ITERATE THROUGH EACH GROUP (ASSUMING MUTUALLY EXCLUSIVE)
for (grp in c("V4", "V5", "V7", "V8")) {

    replace_with <- Summary_Stats_Function(HD_filtered, grp)  

    mergedf <- merge(HD_filtered, replace_with, by=grp)

    # ITERATE THROUGH EACH NUMERIC COLUMN
    for (i in 10:196) {    
         mergedf[[i]][is.na(mergedf[[i]])] <- 
                mergedf[[paste0("V", i,"_mean")]][is.na(mergedf[[i]])]
    }
}