用来自同一列的相等键的值替换特定列中的 NA

Replace NA in a certain column with values from equal key from same column

我基于标准 C 为一组创建了一个均值列。现在我希望在整个列中填写这些均值,即使标准 C 不成立。所以基本上我想用为该组计算的平均值替换 NA。您可以在下一个 Data.table

中看到 grp、val 和 C 列
    grp val C
 1:   1  NA 0
 2:   1  NA 0
 3:   1  42 1
 4:   1  42 1
 5:   2  16 1
 6:   2  16 1
 7:   2  NA 0
 8:   2  NA 0
 9:   3  32 1
10:   3  32 1
11:   3  32 1
12:   3  32 1

所以我想用同一组中的平均值替换val NA。 这是我尝试执行此操作的示例代码。 基本上我提取另一个 data.table,删除 NA 和重复项,然后尝试将其与原始 table.

合并
x <- data.table(grp=c(1,1,1,1,2,2,2,2,3,3,3,3),val=c(NA,NA,42,42,16,16,NA,NA,32,32,32,32),C=c(0,0,1,1,1,1,0,0,1,1,1,1))
y <- x[!is.na(val),]
y <- y[!duplicated(y),]
setkey(x,grp)
setkey(y,grp)
x[y,val:=val,by=grp]

虽然这不会给出任何错误,但它会保留原始列 val 不变。我究竟做错了什么?什么是更好的方法?

为了用组均值估算 NA,data.tabledplyr 效果很好(data.table vs dplyr 是一个单独的讨论)。请参考@David Arenburg 对 data.table 方法代码的评论,以将 NA 替换为均值。

使用 dplyr:

library(dplyr)
df %>% group_by(grp) %>% mutate(val= replace(val, is.na(val), mean(val, na.rm=TRUE))) # ifelse can also be tried instead of replace

不太优雅的方法是通过自定义函数结合 ddply:

library(plyr)
# function to replace NA with mean for that group
impute.mean <- function(x) replace(x, is.na(x), mean(x, na.rm = TRUE))

df <- ddply(df, ~ grp, transform, val = impute.mean(val))

看来这个问题引起了很多 "noise" 的关注,所以我将其添加为答案。

因此 data.table 有一个 "assignment by reference operator",即 :=(请参阅 here 了解更多信息并使用 cases/benchmarks)。

此运算符正在为特定组的 所有 成员赋值(尽管您也可以在不按任何分组的情况下使用它),类似于 mutate 中的函数dplyr or ave and transform in base R, but it by reference (which is ' 对于这个问题特别重要,但可能是它相对于其他 packages/base R) 中的等效项的最大优势,即它正在更新数据集 本身 而不创建副本在使用 <- 运算符时。

总结,如果你想计算一些指标每组并将其分配给每个 该特定组中的值,使用 :=

另一方面,如果您只想要摘要,请改用 =(结合 list() 或仅 .()),或者如果您不想命名聚合的结果,您 根本不需要使用任何东西,如:

x[, .(val = mean(val, na.rm = TRUE)), grp] 

x[, list(val = mean(val, na.rm = TRUE)), grp]

或者只是

x[, mean(val, na.rm = TRUE), grp] # will call the aggregated variable `V1` by default

dplyr 中的等价物是 summarise 而在 base R 中它是 aggregate 或有时 tapply.


也就是说,在您的特定情况下,您将使用 := 运算符将 meanper 组分配给 该特定组中的每个 值,如:

x[, val := mean(val, na.rm = TRUE), grp]