按年汇总数据,仅当该年列中的值时才覆盖行中的 NA

Aggregate data by year and override NA in row ONLY when value in column for that year

假设我有数据框:

 dfTest <- data.frame(year = c(1,2,3,1,3), 
               meanVal = c(1,2,3,1,3),
               var1 = c(1,2,3,1,3),
               var2 = c(NA,2,NA,1,3),
               var3 = c(1,NA,NA,1,3))


 > dfTest
    year meanVal var1 var2 var3
 1    1       1    1   NA    1
 2    2       2    2    2   NA
 3    3       3    3   NA   NA
 4    1       1    1    1    1
 5    3       3    3    3    3

我需要的:

> dfTest
   year meanVal var1 var2 var3
1    1       1    1    1    1
2    2       2    2    2   NA
3    3       3    3    3    3

为此,需要按年份折叠行。如果某列有 NA,则应替换为该列中的值。即第 1 年 (1) 的 var1 只有 1 个值。但是,var1 列中的某些行可能有 NA。此外,如果像我们在第 2 年 var 3 中看到的列只有 NA,则 NA 必须保留。

在 base R 中,这可以用 split/lapply 来完成。

res <- lapply(split(dfTest, dfTest$year), function(DF){
  c(year = unique(DF[["year"]]),
    meanVal = unique(DF[["meanVal"]]),
    colMeans(DF[3:5], na.rm = TRUE)
    )
})
res <- do.call(rbind, res)
is.na(res) <- is.nan(res)

res
#  year meanVal var1 var2 var3
#1    1       1    1    1    1
#2    2       2    2    2   NA
#3    3       3    3    3    3

我们也可以用 base R 中的 aggregate 来做到这一点。创建一个函数来处理每个组只有一行(或具有 all NA 的多行)并且是缺失值的情况。当与 na.rm = TRUE

一起应用时 mean returns NaN 的默认方法
aggregate(.~ year, dfTest, mean, na.rm = TRUE, na.action = NULL)

为避免获得 NaN,创建函数 (f1) 检查每个组的特定列是否 all 元素是 NA。使用 if/else 我们可以 return NA 处理这些情况。

f1 <- function(x) if(all(is.na(x))) NA else mean(x, na.rm = TRUE)
aggregate(.~ year, dfTest, f1, na.action = NULL)
#  year meanVal var1 var2 var3
#1    1       1    1    1    1
#2    2       2    2    2   NA
#3    3       3    3    3    3