R 将NA替换为基于与另一列匹配的行子集的平均值?

R 将NA替换为基于与另一列匹配的行子集的平均值?,r,dataframe,R,Dataframe,我有数据,其中每行包含一个人的性别和体重(以磅为单位): 我搜索了其他问题,但它们与我的问题并不完全相同: “” “” “您可以按性别对数据框进行分组,然后计算重量平均值,并将NA替换为ifelse语句,在dplyr中,它可以是: library(dplyr) df %>% group_by(gender) %>% mutate(weight = ifelse(is.na(weight), mean(weight, na.rm = T), weight))

我有数据,其中每行包含一个人的性别和体重(以磅为单位):

我搜索了其他问题,但它们与我的问题并不完全相同:

“”

“”


您可以按
性别对数据框进行分组,然后计算重量平均值,并将
NA
替换为
ifelse
语句,在
dplyr
中,它可以是:

library(dplyr)
df %>% 
      group_by(gender) %>% 
      mutate(weight = ifelse(is.na(weight), mean(weight, na.rm = T), weight))

# Source: local data frame [9 x 2]
# Groups: gender [2]

#  gender   weight
#  <fctr>    <dbl>
# 1 FEMALE 110.0000
# 2 FEMALE 120.0000
# 3 FEMALE 112.0000
# 4 FEMALE 114.0000
# 5 FEMALE 114.0000
# 6   MALE 190.0000
# 7   MALE 202.0000
# 8   MALE 195.0000
# 9   MALE 195.6667
库(dplyr)
df%>%
按性别划分的组别%>%
变异(重量=ifelse(is.na(重量),平均值(重量,na.rm=T),重量))
#来源:本地数据帧[9 x 2]
#团体:性别[2]
#性别权重
#      
#1女110.0000
#2女120.0000
#3女112.0000
#4女114.0000
#5女114.0000
#6男190.0000
#7男202.0000
#8男195.0000
#9男195.6667

使用base R这似乎就是您要寻找的:

df$weight[df$gender=="FEMALE" & is.na(df$weight)] <- mean(df$weight[df$gender=="FEMALE"], na.rm=TRUE)
df$weight[df$gender=="MALE" & is.na(df$weight)] <- mean(df$weight[df$gender=="MALE"], na.rm=TRUE)

> df
  gender   weight
1 FEMALE 110.0000
2 FEMALE 120.0000
3 FEMALE 112.0000
4 FEMALE 114.0000
5 FEMALE 114.0000
6   MALE 190.0000
7   MALE 202.0000
8   MALE 195.0000
9   MALE 195.6667
df$weight[df$gender==“FEMALE”&is.na(df$weight)]您可以使用
ave()
replace()
(或标准手动更换)


这可以使用
zoo
中的
na.aggregate
轻松完成。将“data.frame”转换为“data.table”(
setDT(df)
),按“性别”分组,我们将
na.aggregate
应用于“权重”,以
平均值替换na元素。默认情况下,
na.aggregate
返回
平均值
,但我们也可以更改
FUN
参数以获得
中值
总和

library(data.table)
library(zoo)
setDT(df)[, weight := na.aggregate(weight) , by = gender]

或者使用
ave
from
base R

with(df, ave(weight, gender, FUN = na.aggregate))
#[1] 110.0000 120.0000 112.0000 114.0000 114.0000 190.0000 202.0000 195.0000 195.6667

这是非常手工的方法。他们将如何为两个以上的群体使用is?在评论中看到一种更普遍的方法,有没有一种方法可以做到这一点,而不需要硬编码“女性”和“男性”?一列中的数据可以有几十个唯一的值。@DavidArenburg很好。看起来Richard Scriven的方法更好,并且在有几个独特价值的情况下有效。谢谢。简单的回答,没有额外的软件包。这正是我想要的。这个
ave()
函数看起来非常强大。新的
coalesce
函数非常适合这里。@alistaire看起来非常有用和方便。
df$weight <- with(df, ave(weight, gender,
    FUN = function(x) replace(x, is.na(x), mean(x, na.rm = TRUE))))
  gender   weight
1 FEMALE 110.0000
2 FEMALE 120.0000
3 FEMALE 112.0000
4 FEMALE 114.0000
5 FEMALE 114.0000
6   MALE 190.0000
7   MALE 202.0000
8   MALE 195.0000
9   MALE 195.6667
library(data.table)
library(zoo)
setDT(df)[, weight := na.aggregate(weight) , by = gender]
with(df, ave(weight, gender, FUN = na.aggregate))
#[1] 110.0000 120.0000 112.0000 114.0000 114.0000 190.0000 202.0000 195.0000 195.6667