数据很复杂。我把数据减少到最小的例子。
X Y
1 10
1 15
1 NA
2 30
2 40
2 NA
我希望通过R中的每个级别填充NA。它似乎很安静,可能与函数apply
或其他内容有关。
结果应为
X Y
1 10
1 15
1 (10 + 15)/2
2 30
2 40
2 (30 + 40)/2
答案 0 :(得分:1)
您可以使用tapply
创建一个查找表,该表可用作检索每个类别的均值的工具。
df <- data.frame(X=c(1, 1, 1, 2, 2, 2), Y=c(10, 15, NA, 30, 40, NA))
match_table <- tapply(df$Y, df$X, mean, na.rm=TRUE)
match_table
# 1 2
# 12.5 35.0
NA_position <- which(is.na(df$Y))
df$Y[NA_position] <- match_table[df$X[NA_position]]
df
# X Y
# 1 1 10.0
# 2 1 15.0
# 3 1 12.5
# 4 2 30.0
# 5 2 40.0
# 6 2 35.0
答案 1 :(得分:0)
可以使用na.aggregate
中的zoo
轻松完成此操作。如果我们使用data.table
(按操作分组),请转换&#39; data.frame&#39;到&#39; data.table&#39; (setDT(df1)
),按&#39; x&#39;分组,我们将NA
值替换为mean
值na.aggregate
并分配(:=
)到新列(&#39; Y1&#39;)。
library(data.table)
library(zoo)
setDT(df1)[, Y1:= na.aggregate(Y), by = X]
df1
# X Y Y1
#1: 1 10 10.0
#2: 1 15 15.0
#3: 1 NA 12.5
#4: 2 30 30.0
#5: 2 40 40.0
#6: 2 NA 35.0
如果我们不需要新的专栏,并且如果我们不需要新专栏,那么该&#39; Y&#39;列为integer
类,输出class
应与之匹配。通过执行mean
,class
将更改为numeric
。因此,请确保最初的&#39; Y&#39;在分配值之前,class为numeric
。
setDT(df1)[, Y:= as.numeric(Y)][, Y:= na.aggregate(Y), X]