将某个列中的NA替换为来自同一列的相同键的值

时间:2015-01-20 13:56:41

标签: r data.table

我基于标准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并重复,然后尝试将其与原始表合并。

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保持不变。我究竟做错了什么?什么是更好的方法?

2 个答案:

答案 0 :(得分:2)

所以看起来这个问题正在推动很多&#34;噪音&#34;,所以我将此作为答案添加。

所以data.table通过引用运算符&#34;进行&#34;赋值。这是:=(有关详细信息和用例/基准,请参阅here)。

此运算符将值分配给所有特定组的成员(尽管您也可以使用它而不进行任何分组),类似于mutate中的dplyr函数或者基础R中的avetransform但是它通过引用来实现(具体来说,这对于这个问题来说并不重要,但它可能是其在其他软件包/基础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,基数R中的等效值为aggregate或有时为tapply


话虽如此,在您的具体情况下,您可以使用:=运算符,以便将每个组的mean分配给每个特定组中的值,如:

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

答案 1 :(得分:1)

如果用组平均值来表示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))