用来自同一列的相等键的值替换特定列中的 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.table
和 dplyr
效果很好(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
.
也就是说,在您的特定情况下,您将使用 :=
运算符将 mean
值 per 组分配给 该特定组中的每个 值,如:
x[, val := mean(val, na.rm = TRUE), grp]
我基于标准 C 为一组创建了一个均值列。现在我希望在整个列中填写这些均值,即使标准 C 不成立。所以基本上我想用为该组计算的平均值替换 NA
。您可以在下一个 Data.table
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.table
和 dplyr
效果很好(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
.
也就是说,在您的特定情况下,您将使用 :=
运算符将 mean
值 per 组分配给 该特定组中的每个 值,如:
x[, val := mean(val, na.rm = TRUE), grp]