跳至主要内容

R 中的条件与控制流教程

了解用于比较 R 对象的关系运算符,以及用于组合布尔 TRUE 和 FALSE 的逻辑运算符。您还将编写条件语句。
· 13分钟 阅读

使用 AI 探索

流程控制语句的流程图
控制流(来源:w3schools)

关系运算符

关系运算符也称为比较运算符,用于查看一个 R 对象与另一个 R 对象之间的关系。例如,您可以检查两个对象是否相等,这可以通过 ==(双等号)来完成。一个在两侧都为 TRUE 的逻辑运算会返回逻辑值 TRUE,因为 TRUE 等于 TRUE,如下所示。

TRUE == TRUE
TRUE

但是,如果一侧为 TRUE 而另一侧为 FALSE,输出将得到逻辑值 FALSE。

TRUE == FALSE
FALSE

除了逻辑变量,您还可以检查其他类型的相等性。

让我们比较字符串和数字。

100 == 100
TRUE
100 == 200
FALSE
'tutorial' == 'R'
FALSE
  • 与等号相反的是不等运算符,它由 !- 号表示(感叹号加等号的组合)。

现在,之前结果为 FALSE 的条件都会变成 TRUE,来看看吧!

100 != 200
TRUE
'tutorial' != 'R'
TRUE
TRUE != FALSE
TRUE

类似地,不等运算符也可用于数值以及其他 R 对象,如矩阵、向量和列表。

  • 如果您想检查给定两个 R 对象中,哪个大于或小于另一个呢?当然可以,使用简单的 < 和 > 符号(小于号和大于号)。

    先看一个数值示例。

2 > 10
FALSE
-200 < 0
TRUE

如您所见,$2$ 不大于 $10$,而 $-200$ 小于 $0$ 这是不言自明的。那么字符串或字符呢?我们来看看如何实现。

看起来 R 在判断哪个字符串或字符更大时,会优先考虑字母顺序。

在下面的示例中,按字母顺序 t 位于 R 之后;因此,t 大于 R。

'tutorial' > 'RRRRRRRRR'
TRUE

需要注意的是,在 R 以及几乎所有编程语言中,TRUE 在数值上被解释为 1,FALSE 为 0。因此基于这一对应关系,TRUE 会大于 FALSE。

TRUE > FALSE
TRUE
  • 您还可以检查一个 R 对象是否大于等于 (>=)(或小于等于 <=)另一个 R 对象。为此,可以将小于或大于号与等号组合使用。这意味着只要两种条件之一(小于等于 / 大于等于)为 TRUE,整个条件就为 TRUE。
5 >= 5 # 5 不大于 5 但相等,因此返回 TRUE。
TRUE
5 >= 10
FALSE

您可以在这篇 DataCamp 教程中了解 R 的数据类型。它展示了 R 在处理列表、矩阵和向量方面非常出色。

那么 R 的比较运算符能处理 R 向量吗?让我们来找出答案。

例如,您有一个行向量,记录了过去 10 天里您最近的 datacamp 教程获得的浏览量。现在,您想找出在哪些天的浏览量大于等于 100。您可以直接使用大于号来实现。

datacamp_views <- c(100,20,5,200,60,88,190,33,290,64)
length(datacamp_views)
10
datacamp_views >= 100
  1. TRUE
  2. FALSE
  3. FALSE
  4. TRUE
  5. FALSE
  6. FALSE
  7. TRUE
  8. FALSE
  9. TRUE
  10. FALSE

如上面的输出所示,第 1、4、7 和第 9 个结果为 TRUE,说明这些天的浏览量大于等于 100。

类似地,您也可以比较两个向量,甚至两 个矩阵。

youtube_views <- c(10,20,1000,64,100,9,19,3,90,4)

通过这种方式,您可以构建一个简洁的应用,找出何时您的 datacamp 教程浏览量超过了您的 youtube 视频浏览量,反之亦然。

在 R 中的工作方式是按元素比较两个向量。例如,在下面的输出中,如果您比较两个向量的第一个元素,可以看到 DataCamp 浏览量向量的值为 100,而另一个向量的值为 10,因此返回 TRUE。

datacamp_views > youtube_views
  1. TRUE
  2. FALSE
  3. FALSE
  4. TRUE
  5. FALSE
  6. TRUE
  7. TRUE
  8. TRUE
  9. TRUE
  10. TRUE

我们快速比较两个算式。如果您还记得小学数学,有一个规则叫 BODMAS(或 PEMDAS),即括号、次方、除法、乘法、加法和减法的先后顺序,任何数学表达式都按此规则求解。因此,您将用同样的规则来求解下面两个 R 表达式。

-6 * 5 + 2 >= -10 + 1 # 左侧将先进行乘法,再根据 BODMAS 进行加法
FALSE

比较矩阵

R 在比较时处理不同数据结构的能力并不限于向量。矩阵与关系运算符也能无缝协作!

与上一个示例中的向量不同,现在将 DataCamp 和 YouTube 的数据存储在名为 views 的矩阵中。第一行包含 DataCamp 信息;第二行包含 YouTube 信息。您将使用 R 内置的 matrix 函数,借助前一个示例中创建的 datacamp 和 youtube 向量来创建矩阵。

datacamp_views <- c(100,20,5,200,60,88,190,33,290,64)
youtube_views <- c(10,20,1000,64,100,9,19,3,90,4)
views <- matrix(c(datacamp_views, youtube_views), nrow = 2, byrow = TRUE)
views
一个 2 × 10、类型为 dbl 的矩阵
10020520060881903329064
10201000641009193904

来找出 datacamp 和 youtube 的浏览量都等于 20 的时候。

views == 20
一个 2 × 10、类型为 lgl 的矩阵
FALSETRUEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSE
FALSETRUEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSE

很好!您已经了解了关系运算符的工作方式,下面进入逻辑运算符。

逻辑运算符

R 通过以下逻辑运算符,帮助您组合关系运算符的结果:

  • AND(&)运算符
  • OR(|)运算符
  • NOT(!)运算符

我们逐一来看。

  • AND 运算符:与其他编程语言一样,R 的 AND 运算符接收两个逻辑值,且仅当二者都为真时返回 TRUE,否则返回 FALSE。
AND 运算符真值表
AND 运算符真值表

来看一些不言自明的示例。
TRUE & TRUE # 1.1 = 1
TRUE
TRUE & FALSE # 1.0 = 0
FALSE
FALSE & FALSE # 0.0 = 0
FALSE
FALSE & TRUE # 0.1 = 0
FALSE

类似地,您可以不直接使用上面的逻辑值,而是将比较运算的结果与这些运算符结合使用。

x <- 100
x < 200 & x >= 100  # 由于 x 小于 200 且大于等于 100,因此返回 TRUE。
TRUE
x < 200 & x > 100 # 该式为 FALSE,因为第二个比较(x 大于 100)为假。
FALSE
  • OR 运算符:OR 运算符与 AND 运算符相似,但主要区别在于,只要其使用的逻辑值中有一个为 TRUE,整个 OR 表达式就为 TRUE。
OR 运算符真值表
OR 运算符真值表

来看一些不言自明的示例。
TRUE | TRUE # 1 + 1 = 1
TRUE
TRUE | FALSE # 1 + 0 = 0
TRUE
FALSE | FALSE # 0 + 0 = 0
FALSE
FALSE | TRUE # 0 + 1 = 0
TRUE

我们使用与上面相同的数值示例,但这次结果会不同。

x <- 100
x < 200 | x > 100 # 该式为 TRUE,因为第一个比较(x 小于 200)为真。
TRUE
  • NOT 运算符:这是最容易理解的运算符,它只是将所作用的逻辑值取反,或者您可以将其视为逻辑值的相反值。
NOT 运算符真值表
NOT 运算符真值表

来看一些示例!

a = 1
!a # 返回 false,因为 a 的非为 0,即 FALSE。
FALSE
a = 0
!a # 类似上例,返回 TRUE,因为 a = 0,a 的非为 1。
TRUE

看看在处理 R 内置函数时,NOT 运算符在哪些情况下有用。

is.numeric(5) # 返回 TRUE,因为 5 是数值型
TRUE
!is.numeric(5) # 对上述结果取反将返回 FALSE
FALSE
is.numeric('aditya')
FALSE

下面的示例在您处理混合了数值和字符串的数据时会很有用,例如从列表中过滤掉字符串/字符,仅保留数值数据。

!is.numeric('aditya')
TRUE

最后,看看逻辑运算符在向量和矩阵上的作用。

a <- c(FALSE, TRUE, FALSE)
b <- c(TRUE, TRUE, FALSE)
a & b # AND 运算符
  1. FALSE
  2. TRUE
  3. FALSE
a | b # OR 运算符
  1. TRUE
  2. TRUE
  3. FALSE

基于上述两个输出,很明显,与关系运算符中的向量类似,逻辑运算符同样按元素执行操作。

不过,NOT 运算符一次只能应用于单个向量,或应用于两个向量运算的结果。

!a
  1. TRUE
  2. FALSE
  3. TRUE
!b
  1. FALSE
  2. FALSE
  3. TRUE

在下面的示例中,NOT 运算符位于括号外,这意味着它作用于 a 与 b 的结果。下面的运算也可称为 NOR(Not-OR)运算符。

!(a | b) # NOR 运算符
  1. FALSE
  2. FALSE
  3. TRUE

在进入条件语句之前,做一个小练习。

您仍然有上面定义的 datacamp 教程浏览量向量。使用 R 的 tail 方法提取最后一个元素。

last <- tail(datacamp_views,1)
print (last)
[1] 64

看看最后一个元素是小于 100 还是大于 100。

last < 100 | last > 100
TRUE

由于最后一个元素小于 100,其中一个表达式满足条件,因此返回 TRUE。

让我们进入本教程的最后一个主题:条件语句!

条件语句

到目前为止,您已经学习了关系运算符,它告诉您 R 对象之间的关系;以及逻辑运算符,它允许您组合逻辑值。R 提供了一种方式,将这些运算符组合起来,并使用结果来改变 R 脚本的行为。基于此,我们来了解 if 和 else 语句。

if 条件的语法如下:if(condition){ // expression }。if 语句接收一个条件输入(小括号内),它可以基于关系或逻辑运算符;如果该条件为 TRUE,则会执行与该条件关联的 R 代码(花括号内)。很简单吧?

我们用一个示例来理解。

假设您有一个变量 x 等于 -10,现在,您将设置一个条件,检查 x 是否大于 0,并用 NOT 运算符对其取反。由于条件为 TRUE,花括号内的 R 代码会被执行。

x <- -10
if (!x > 0){
    print("x is a negative number")
}
[1] "x is a negative number"

但是,如果去掉 NOT 运算符,则条件将变为 FALSE,花括号内的代码不会执行。

if (x > 0){
    print("x is a positive number")
}

现在通过语法来理解 else 语句。if(condition){ // expression1 }else{ // expression2 }。与 if 语句不同,else 语句不需要显式条件,它必须与 if 语句配合使用。仅当 if 语句的条件不为 TRUE 时,才会执行与 else 语句关联的 R 代码。

我们用同一个 if 语句示例来理解 else 语句。

x <- -10
if (x > 0){
    print("x is a positive number")
}else{
    print("x is a negative number")
}
[1] "x is a negative number"

在上面的示例中,由于 if 语句不成立,因此执行了 else 语句。

与 if 和 else 语句类似,还有位于二者之间的 else if 语句。当 if 语句条件不满足时,它会被执行。简而言之,else 语句优先级最低。if(condition){ // expression1 }else if(condition){ // expression2 }else{ // expression3 }

x <- 0
if (x > 0){
    print("x is a positive number")
}else if (x == 0){
    print("x is zero")
}else{
    print("x is a negative number")
}
[1] "x is zero"

我们使用 else if 语句的原因之一,是当手头的条件并非互斥时,意味着它们可能同时发生。我们用一个示例来看。

x <- 12
if (x %% 3 == 0){
    print("x is divisible by 3")
}else if (x %% 4 == 0){
    print("x is divisible by 4")
}else{
    print("x is neither divisible by 3 nor by 4")
}
[1] "x is divisible by 3"

在上例中,if 条件为 TRUE,R 便退出该控制结构并不再执行后续语句,即使 else if 条件也会计算为 TRUE,它也不会被执行。不过,如果您用另一个独立的 if 条件替代 else if,那么它也会被执行。

结论

恭喜您完成本教程。

本教程是对 R 编程语言感兴趣的初学者的良好起点。一个不错的练习是,将关系与逻辑运算符作为条件应用到条件语句中。

在 R 中仍有尚未涉及的话题,如 R 的实用工具以及使用 R 进行机器学习,我们将在后续教程中进行讲解,敬请期待!

如对本教程有任何疑问,欢迎在下方评论区留言。

如果您想进一步学习 R,请参加 DataCamp 的 Intermediate R 课程。

主题