跳至主要内容

如何在 R 中使用 na.rm 处理缺失值

我们在常见的 R 函数中设置 na.rm = TRUE 以排除缺失值(NA)。这有助于我们计算准确的统计量并提升结果的可靠性。
· 8分钟 阅读

使用 AI 探索

数据正以工业化的速度被生成与消费,用于推动关键业务决策。然而,数据分析的一个常见挑战是缺失值的存在。这会扭曲结果,因此任何数据分析师都必须有效地处理它们。在 R 中,管理缺失值的基础工具之一就是 na.rm 参数。

本文将解释处理缺失数据的重要性、na.rm 在 R 中如何工作,展示其在各种函数中的用法,并最后讨论一些识别和处理缺失数据的替代技术。

简答版:什么是 na.rm?

R 中的 na.rm 参数意为“移除 NA”,在计算过程中忽略 NA(缺失)值。通过设置 na.rm = TRUE,诸如 mean()、sum()、min()、max()、median() 和 sd() 等函数会在不受缺失值影响的情况下进行计算。

na.rm 参数以小写书写,取布尔值——TRUE 或 FALSE。当我们设置 na.rm = TRUE 时,R 会在计算中排除 NA 值。如果不设置该参数,一旦数据中存在缺失值,这些函数将返回 NA。请看示例。

vector_with_na <- c(1, 2, NA)

sum(vector_with_na, na.rm = TRUE) # removes NA values — returns 3
sum(vector_with_na) # includes NA values — returns NA
sum(vector_with_na, na.rm = FALSE) # includes NA values — returns NA

想进一步了解 R 编程基础,请查看 Introduction to R 课程。

为什么要使用 na.rm?

在数据分析中,处理缺失值对于确保结果准确至关重要,因为它们会显著影响统计计算,进而无意间导致错误结论。使用 na.rm 可以方便地跳过这些缺失值,从而避免错误,执行可靠的计算,并维护数据完整性。

Data Cleaning in R 课程有助于进一步提升我们的数据分析技能。

使用 na.rm 的常见函数:一些实用示例

现在,让我们来了解如何在 R 中使用 na.rm。有多个 R 函数包含 na.rm 参数(默认设为 FALSE)。以下是一些常见示例:

sum()

顾名思义,sum() 计算向量中数值的总和。我们创建一个名为 vector_with_na 的向量,并在整个教程中使用它。

vector_with_na <- c(1, 2, NA, 4)

sum(vector_with_na) 
# Returns NA

sum(vector_with_na, na.rm = TRUE) 
# Returns 7

mean()

沿用同一示例,mean() 函数用于计算均值,即向量中数值的平均值。

mean(vector_with_na) 
# Returns NA

mean(vector_with_na, na.rm = TRUE) 
# Returns 2.33

sd()

继续使用 vector_with_na,sd() 计算该向量的标准差。

sd(vector_with_na) 
# Returns NA

sd(vector_with_na, na.rm = TRUE) 
# Returns 1.53

min()

min() 用于查找最小值。

min(vector_with_na) 
# Returns NA

min(vector_with_na, na.rm = TRUE) 
# Returns 1

max()

max() 用于查找最大值。

max(vector_with_na) 
# Returns NA

max(vector_with_na, na.rm = TRUE) 
# Returns 4

median()

median() 在有序排列后查找中位数。

median(vector_with_na) 
# Returns NA

median(vector_with_na, na.rm = TRUE) 
# Returns 2

请注意,如果不设置 na.rm = TRUE,上述所有聚合函数都会返回 NA。

通过设置 na.rm = TRUE,这些函数会排除 NA 值,从而得到准确且有意义的计算结果。想更好地理解这些函数的用法与语法,可以参考 R Programming Fundamentals 技能路径。

在不同数据结构中处理缺失值

让我们看看如何在不同数据结构中处理缺失值。在继续之前,若您想进一步了解 R 的数据结构,请查看我们的 R 编程语言数据结构精通指南 教程。

向量(Vectors)

在向量中,可以直接在函数内使用 na.rm 来排除缺失值。上一节的示例都是 na.rm 在向量上的用法。

数据框(Data frames)

对于数据框,可以在针对特定列的函数中使用 na.rm,或结合 apply() 跨行应用,如下所示:

apply(X, MARGIN, FUN)

其中:

  • X:数组、数据框或矩阵

  • MARGIN:用于指明函数应用的维度:

    • MARGIN=1 按行操作

    • MARGIN=2 按列操作

    • MARGIN=c(1,2) 同时按行和列操作

  • FUN:要应用的函数。可使用内置函数如 mean()、median()、sum()、min()、max(),也可使用自定义函数。

让我们创建一个数据框,便于在本教程中引用。

dataframe_with_na <- data.frame(col1 = c(1, NA, 3, 6), col2 = c(4, 5, NA, 7))

print(dataframe_with_na)
# Returns
#   col1 col2
# 1    1    4
# 2   NA    5
# 3    3   NA
# 4    6    7

apply(dataframe_with_na, 1, mean)
# Returns
# [1] 2.5  NA  NA 6.5

apply(dataframe_with_na, 1, mean, na.rm = TRUE)
# Returns
# [1] 2.5 5.0 3.0 6.5

apply(dataframe_with_na, 2, mean)
# Returns
# col1 col2 
#  NA   NA 

apply(dataframe_with_na, 2, mean, na.rm = TRUE)
# Returns   
#   col1     col2 
# 3.333333 5.333333

列表(Lists)

R 中的 lapply() 函数用于将指定函数应用到列表、向量或数据框的每个元素上,并返回相同长度的列表。此函数不需要 MARGIN 参数,因为它会自动对所有元素进行操作。

语法:

lapply(vector_with_na, fun)

其中:

  • vector_with_na:输入的列表、向量或数据框。
  • fun:要应用到每个输入数据元素的函数。

让我们用一个列表示例来理解 lapply()。这里我们有一个集合列表(item_1 和 item_2),其元素与数据框(dataframe_with_na)类似。我们的目标是求出每个集合的均值。

list_with_na <- list(item_1=c(1, NA, 3, 6), item_2=c(4, 5, NA, 7))

lapply(list_with_na, mean)
# Returns
# $item_1
# [1] NA
# 
# $item_2
# [1] NA

lapply(list_with_na, mean, na.rm =TRUE)
# Returns
# $item_1
# [1] 3.333333
# 
# $item_2
# [1] 5.333333

sapply() 与 lapply() 类似,但返回的是数组或矩阵而非列表。我们使用列表(list_with_na)和 sapply() 来计算其中每个集合的均值。

sapply(list_with_na, mean)
# Returns
# a  b 
# NA NA 

sapply(list_with_na, mean, na.rm = TRUE)

# Returns
# a        b 
# 3.333333 5.333333

现在,让我们用数据框(dataframe_with_na)和 sapply() 来计算各列数值之和。

sapply(dataframe_with_na, sum)

# Returns
# col1 col2 
# NA   NA 

sapply(dataframe_with_na, sum, na.rm=TRUE)
# Returns
# col1 col2 
# 10   16

想更全面地了解 R 中的数据处理,强烈推荐 Data Manipulation with dplyr 课程。如果您对 apply() 家族函数不太熟悉,可阅读我们的 R Apply 家族教程。

与 na.omit() 和 complete.cases() 的比较

na.omit():该函数会移除数据框中包含 NA 值的所有行。来看一个例子:

na.omit(dataframe_with_na)
# Returns
# col1 col2
# 1    1    4
# 4    6    7

complete.cases():另一方面,complete.cases() 用于识别不含任何 NA 值的行,并返回与每一行对应的布尔值(含 NA 的行为 FALSE,反之为 TRUE)。这可用于筛选数据框中的非缺失行,如下所示。

complete.cases(dataframe_with_na)
# Returns
# [1]  TRUE FALSE FALSE  TRUE

dataframe_with_na[complete.cases(dataframe_with_na), ]
# Returns
# col1 col2
# 1    1    4
# 4    6    7

处理缺失值的高级技巧

除了 na.rm,R 还提供了处理缺失数据的高级方法:

使用 is.na() 识别缺失值

is.na() 可直接应用于向量或数据框以识别缺失数据。它会对每个缺失值返回 TRUE。

is.na(vector_with_na)
# Returns
# [1] FALSE FALSE  TRUE FALSE

is.na(dataframe_with_na)
# Returns
# col1  col2
# [1,] FALSE FALSE
# [2,]  TRUE FALSE
# [3,] FALSE  TRUE
# [4,] FALSE FALSE

应用插补方法

插补通过估计值(如均值或中位数)替换缺失值,如下所示:

vector_with_na[is.na(vector_with_na)] <- mean(vector_with_na, na.rm = TRUE)

print(vector_with_na)
# Returns
# [1] 1.000000 2.000000 2.333333 4.000000

dataframe_with_na[is.na(dataframe_with_na)] <- sapply(dataframe_with_na, mean, na.rm=TRUE)
print(dataframe_with_na)
# Returns
# col1     col2
# 1 1.000000 4.000000
# 2 3.333333 5.000000
# 3 3.000000 5.333333
# 4 6.000000 7.000000

使用 summary() 函数

有趣的是,summary() 在处理缺失值方面与使用 na.rm 不同。默认情况下,summary() 在计算汇总统计时会自动排除缺失值,并随后报告数据中 NA 的数量。

让我们对向量 vector_with_na 运行 summary():

summary(vector_with_na)
#Returns
#   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
#  1.000   1.500   2.000   2.333   3.000   4.000       1

再对数据框 dataframe_with_na:

summary(dataframe_with_na)
# Returns
# col1           col2     
# Min.   :1.00   Min.   :4.00  
# 1st Qu.:2.50   1st Qu.:4.75  
# Median :3.00   Median :5.00  
# Mean   :3.25   Mean   :5.25  
# 3rd Qu.:3.75   3rd Qu.:5.50  
# Max.   :6.00   Max.   :7.00 

Intermediate R 课程为希望了解更高级数据处理技巧的读者提供了深入见解。

处理缺失值的最佳实践

要有效处理缺失值,可遵循以下最佳实践:

始终检查缺失值

在执行计算前,先识别并了解缺失数据的程度。下面的示例显示该数据框共有 2 个缺失值。

print(dataframe_with_na)
# Returns
# col1 col2
# 1    1    4
# 2   NA    5
# 3    3   NA
# 4    6    7

sum(is.na(dataframe_with_na))
# Returns
# [1] 2

使用条件检查

始终验证是否存在缺失数据,并据此应用任何插补技术,确保各类边界情况都得到妥善处理。

if(any(is.na(dataframe_with_na))) {  
  if (class(dataframe_with_na) == "data.frame") {    
   dataframe_with_na[is.na(dataframe_with_na)] <- sapply(dataframe_with_na, median, na.rm=TRUE)      
  }
}

print(dataframe_with_na)
# Returns
# col1 col2
# 1    1    4
# 2    3    5
# 3    3    5
# 4    6    7

结合上下文做判断

理解数据为何缺失,并选择合适的方法进行处理——删除或插补。

若想系统化地进行数据分析并处理缺失值,Data Cleaning in R 课程会是很好的资源。

结语

理解并使用 na.rm 是确保数据分析可靠且准确的关键。在 R 项目中多练习使用 na.rm,并探索更高级的技术,全面处理缺失数据。

想要进一步学习,可查看以下资源:

Vidhi Chugh

作者

Vidhi Chugh

我是一名 AI 策略与伦理专家,致力于在数据科学、产品与工程的交汇处构建可扩展的机器学习系统。曾入选全球“200 位顶尖商业与技术创新者”之一,我的使命是让机器学习走向大众,打破术语壁垒,让每个人都能参与这场变革。

常见问题解答

R 中的 na.rm 参数是什么?

R 中的 na.rm 参数意为“移除 NA”。当设置为 TRUE 时,它会指示函数在计算过程中忽略 NA(缺失)值,以确保结果准确。

如何在 R 的常见函数中使用 na.rm?

您可以在 sum()、mean()、sd()、min()、max() 和 median() 等函数中通过设置 na.rm = TRUE 来使用 na.rm,以在计算中排除缺失值。

为什么在数据分析中处理缺失值很重要?

缺失值会扭曲结果并导致不准确的结论。有效地处理它们能确保计算可靠并维护数据完整性。

na.rm 能与 R 中的数据框和列表一起使用吗?

是的,na.rm 可与数据框配合使用(如通过 apply()),也可与列表配合使用(如 lapply() 和 sapply()),以在对这些数据结构进行操作时排除缺失值。

在 R 中处理缺失值有哪些高级技巧?

除 na.rm 外,高级技巧包括使用 is.na() 识别缺失值、应用插补方法进行替换,以及使用 na.omit() 与 complete.cases() 等函数进行更复杂的数据清洗。

主题