如何在 R 中替换缺失值 (NA):na.omit 和 na.rm

数据科学中的缺失值是指数据框中某一列的观测值缺失或包含字符值而非数值。必须删除或替换缺失值才能从数据中得出正确的结论。

在本教程中,我们将学习如何使用 dplyr 库处理缺失值。dplyr 库是实现数据分析的生态系统的一部分。

在 R 中替换缺失值

在本教程中,您将学习

变异()

第四个动词 dplyr 库 有助于创建新变量或改变现有变量的值。

我们将分两部分进行。我们将学习如何:

  • 从数据框中排除缺失值
  • 用平均值和中位数填补缺失值

动词 mutate() 非常容易使用。我们可以按照以下语法创建一个新变量:

mutate(df, name_variable_1 = condition, ...)
arguments:
-df: Data frame used to create a new variable
-name_variable_1: Name and the formula to create the new variable
-...: No limit constraint. Possibility to create more than one variable inside mutate()

排除缺失值 (NA)

dplyr 库中的 na.omit() 方法是排除缺失观察值的简单方法。从数据中删除所有 NA 很容易,但这并不意味着它是最优雅的解决方案。在分析过程中,明智的做法是使用各种方法来处理缺失值

为了解决缺失观测值的问题,我们将使用泰坦尼克号数据集。在这个数据集中,我们可以访问悲剧发生期间船上乘客的信息。这个数据集有许多需要处理的 NA。

我们将从互联网上传 csv 文件,然后检查哪些列有 NA。要返回缺少数据的列,我们可以使用以下代码:

让我们上传数据并验证缺失的数据。

PATH <- "https://raw.githubusercontent.com/guru99-edu/R-Programming/master/test.csv"
df_titanic <- read.csv(PATH, sep = ",")
# Return the column names containing missing observations
list_na <- colnames(df_titanic)[ apply(df_titanic, 2, anyNA) ]
list_na

输出:

## [1] "age"  "fare"

在这里,

colnames(df_titanic)[apply(df_titanic, 2, anyNA)]

给出没有数据的列的名称。

年龄和票价列缺少值。

我们可以使用 na.omit() 删除它们。

library(dplyr)
# Exclude the missing observations
df_titanic_drop <-df_titanic %>%
na.omit()		
dim(df_titanic_drop)

输出:

## [1] 1045   13

新的数据集包含 1045 行,而原始数据集包含 1309 行。

排除缺失值

使用平均值和中位数填补缺失数据

我们还可以用中位数或均值来填补缺失值。一个好的做法是为均值和中位数创建两个单独的变量。创建后,我们可以用新形成的变量替换缺失值。

我们将使用 apply 方法来计算 NA 列的平均值。让我们看一个例子

步骤1) 在本教程的前面,我们将包含缺失值的列名称存储在名为 list_na 的列表中。我们将使用此列表

步骤2) 现在我们需要使用参数 na.rm = TRUE 来计算平均值。此参数是必需的,因为列中有缺失数据,这会告诉 R 忽略它们。

# Create mean
average_missing <- apply(df_titanic[,colnames(df_titanic) %in% list_na],
      2,
      mean,
      na.rm =  TRUE)
average_missing

代码说明:

我们在apply方法中传递了4个参数。

  • df:df_titanic[,colnames(df_titanic) %in% list_na]。此代码将从 list_na 对象中返回列名称(即“age”和“fare”)
  • 2:计算列上的函数
  • 平均值:计算平均值
  • na.rm = TRUE:忽略缺失值

输出:

##      age     fare 
## 29.88113 33.29548

我们成功创建了包含缺失观测值的列的平均值。这两个值将用于替换缺失的观测值。

步骤3) 替换 NA 值

dplyr 库中的动词 mutate 在创建新变量时很有用。我们不一定想更改原始列,因此我们可以创建一个没有 NA 的新变量。mutate 易于使用,我们只需选择一个变量名并定义如何创建此变量。以下是完整代码

# Create a new variable with the mean and median
df_titanic_replace <- df_titanic %>%
   mutate(replace_mean_age  = ifelse(is.na(age), average_missing[1], age),
   replace_mean_fare = ifelse(is.na(fare), average_missing[2], fare))

代码说明:

我们创建两个变量,replace_mean_age 和 replace_mean_fare 如下:

  • replace_mean_age = ifelse(is.na(年龄), average_missing[1], 年龄)
  • replace_mean_fare = ifelse(is.na(fare), average_missing[2],fare)

如果 age 列有缺失值,则用 average_missing 的第一个元素(年龄平均值)替换,否则保留原始值。fare 的逻辑相同

sum(is.na(df_titanic_replace$age))

输出:

## [1] 263

执行替换

sum(is.na(df_titanic_replace$replace_mean_age))

输出:

## [1] 0

原始列年龄有 263 个缺失值,而新创建的变量已用变量年龄的平均值替换它们。

步骤4) 我们也可以用中位数替换缺失的观测值。

median_missing <- apply(df_titanic[,colnames(df_titanic) %in% list_na],
      2,
      median,
      na.rm =  TRUE)
df_titanic_replace <- df_titanic %>%
            mutate(replace_median_age  = ifelse(is.na(age), median_missing[1], age), 
            replace_median_fare = ifelse(is.na(fare), median_missing[2], fare))
head(df_titanic_replace)

输出:

使用平均值和中位数填补缺失数据

步骤5) 大数据集可能有很多缺失值,上述方法可能很麻烦。我们可以使用 sapply() 方法在一行代码中执行上述所有步骤。尽管我们不知道平均值和中位数的值。

sapply 不会创建 数据框,因此我们可以将 sapply() 函数包装在 data.frame() 中来创建一个数据框对象。

# Quick code to replace missing values with the mean
df_titanic_impute_mean < -data.frame(
    sapply(
        df_titanic,
        function(x) ifelse(is.na(x),
            mean(x, na.rm = TRUE),
            x)))

结语

我们有三种方法来处理缺失值:

  • 排除所有缺失的观测值
  • 用平均值估算
  • 使用中位数进行估算

下表总结了如何删除所有缺失的观察值

自学资料库 目的 代码
基地 列出缺失的观察结果
colnames(df)[apply(df, 2, anyNA)]
dplyr 删除所有缺失值
na.omit(df)

用平均值或中位数进行插补可以通过两种方式进行

  • 使用 apply
  • 使用 sapply
付款方式 信息 性能 缺点
逐步应用 检查缺失的列,计算平均值/中位数,存储值,用 mutate() 替换 您知道平均值/中位数的值 执行时间更长。处理大数据集时速度会比较慢
使用 sapply 的快捷方式 使用 sapply() 和 data.frame() 自动搜索缺失值并用平均值/中位数替换 代码短、速度快 不知道归纳值