如何完成代码以在 R 中用中位数替换 NA

How to finish code to replace NA with median in R

我是R的新手,所以请温柔点。

我正在参加 Kaggle 泰坦尼克号竞赛,让我进入 R 并解决问题。

我正在努力设计一个功能,但我对下一步该做什么的逻辑有点困惑。

那么,开始吧。我的目标是获取年龄数据并将所有 NA 替换为该人头衔的年龄中位数。例如如果这个人是大师,我想得到所有大师的中位数,并用那个中位数替换 NA。先生等同理

我已经成功地为自己创建了一个 data.frame 包含标题和年龄如下:

library(tibble)
data.combined <-
  tibble(
    data.combined.new.title = c(
      "Mr.",
      "Mrs.",
      "Miss",
      "Mrs.",
      "Mr.",
      "Mr.",
      "Mr.",
      "Master",
      "Mrs."
    ),
    data.combined.Age = c(22, 38, 26, 35, 35, NA, 54, 2, 27)
  )

如您所见,在此列表中有一位先生和 NA 在他的年龄旁边。我想用列表中所有其他先生的中位数替换那个 NA。

所以我有以下代码,直到我可以用整个数据集的中值替换 NA。

#Creates my data.frame
agedata <- data.frame(data.combined$new.title, data.combined$Age)

#replace NA with the mean of the whole data set
agedata$data.combined.Age[is.na(agedata$data.combined.Age)] <- median(agedata$data.combined.Age, na.rm = TRUE)

我只是不明白的是,我该如何添加到此代码中以用先生、硕士、夫人、小姐等头衔组的中位数替换 NA?

不胜感激指点

目前我对这是否有助于我对 Kaggle 的预测不太感兴趣,更多的是代码的外观。

非常感谢。

zz <- "group traits
BSPy01-10     NA
BSPy01-10    7.3
BSPy01-10    7.3
BSPy01-11    5.3
BSPy01-11    5.4
BSPy01-11    5.6
BSPy01-11     NA
BSPy01-11     NA
BSPy01-11    4.8
BSPy01-12    8.1
BSPy01-12    6.0
BSPy01-12    6.0
BSPy01-13    6.1"
Data <- read.table(text=zz, header = TRUE)

impute <- function(x, fun) {
missing <- is.na(x)
replace(x, missing, fun(x[!missing]))
}
ddply(Data, ~ group, transform, traits = impute(traits, median))

这可能不是最优雅的方法,但它确实有效:

title <- c("Mr", "Mrs", "Miss", "Mrs", "Mr", "Mr", "Mr", "Master", "Mrs")
age <- c(22, 38, 26, 35, 35, NA, 54, 2, 27)
df = data.frame(title, age)

# get the medians by groups
medians = aggregate(df$age, list(df$title), median, na.rm = TRUE)
# match the missing ages with the medians thanks to the groups
df$age[is.na(df$age)] <- medians[array(medians$Group.1) == df$title[is.na(df$age)], "x"]

library(data.table)

dt <- data.table(title = c("Mr", "Mrs", "Miss", "Mrs", "Mr", "Mr", "Mr", "Master", "Mrs"),
age = c(22, 38, 26, 35, 35, NA, 54, 2, 27))

dt[,avg_age:=median(age,na.rm=T),by="title"]
dt[is.na(age),age:=avg_age]
dt[,avg_age:=NULL]

或者这tidyverse单行

agedata %>% group_by(title) %>% mutate(age=ifelse(is.na(age), median(age, na.rm=TRUE), age))