迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 >

R 中具有多个条件的函数向量化

作者:迹忆客 最近更新:2023/03/21 浏览次数:

一项常见的数据分析任务是根据同一行的其他列使用一个或多个条件创建或更新数据框列。

如果我们尝试使用 if 语句来执行此操作,则只会使用第一行来测试条件,并且会根据该行更新整列。

在处理数据框时,我们需要适用于多行的工具和技术。 本文将学习矢量化 if 函数和矢量化 AND 和 OR 运算符以组合多个条件。

我们将首先创建一个小数据框用于说明。

# Create two vectors.
Col1 = rep(c("A", "B"), times = 2, each = 2)
Col2 = rep(c("x", "y"), times = 1, each = 4)

# Create a data frame.
cond_df = data.frame(Col1, Col2)

# View the data frame.
cond_df

R 中 if 语句的限制

根据文档,if 语句采用非 NA 的长度为一的逻辑向量……仅使用第一个元素。

在以下示例中,我们将根据使用另一列的条件创建一列。

# 尝试使用if语句
cond_df$NewCol = if(Col1 == "B"){cond_df$NewCol = "Col1 was B"} else{cond_df$NewCol = "Col1 was not B"}

# 查看结果
cond_df

输出结果

 Col1 Col2         NewCol
1    A    x Col1 was not B
2    A    x Col1 was not B
3    B    x Col1 was not B
4    B    x Col1 was not B
5    A    y Col1 was not B
6    A    y Col1 was not B
7    B    y Col1 was not B
8    B    y Col1 was not B

当我们执行此 if 语句但创建列时,R 发出警告。 结果不是我们想要的。

仅评估第一行,并将结果应用于所有数据框行。


R 中的矢量化 ifelse() 函数

Base R 包含一个向量化的 ifelse() 函数,我们可以使用它有条件地更新数据框列。

根据文档,此函数“……返回一个与测试形状相同的值……”,这使其适合在数据框上使用。

该函数的语法是:ifelse(test, value_if_true, value_if_false)。 下面的代码说明了这个函数的用法。

# 使用相同的向量创建一个新的数据框。
vect_df = data.frame(Col1, Col2)

# 使用向量化的 ifelse() 函数。
vect_df$NewCol = ifelse(Col1 == "B", "Col1 was B", "F")

# view the result.
vect_df

输出结果

> vect_df
  Col1 Col2     NewCol
1    A    x          F
2    A    x          F
3    B    x Col1 was B
4    B    x Col1 was B
5    A    y          F
6    A    y          F
7    B    y Col1 was B
8    B    y Col1 was B

此函数按照预期执行。 我们可以使用它根据其他列的值使用条件来创建或更新数据框列。

但是这个功能有一个限制。 文档说明 ifelse() 剥离属性。 这在处理日期和因素时很重要。

让我们看一个问题的例子,它们是:

  • 创建一个日期向量。
  • 在第一个向量上使用 ifelse() 函数创建一个新向量。 ifelse() 函数引起的更改是意外的。
# 创建和查看日期向量。
datevec = seq(from = as.Date("2022-01-01"), to = as.Date("2022-01-05"), by = "day")
datevec
class(datevec)

# 在前一个向量上使用 ifelse() 函数创建一个新的日期向量。 查看它。
mod_datevec = ifelse(datevec < as.Date("2022-01-03"), datevec, as.Date("2022-02-01"))
mod_datevec # 不是预期的结果.
class(mod_datevec) # Not date.

输出结果

> datevec = seq(from = as.Date("2022-01-01"), to = as.Date("2022-01-05"), by = "day")
> datevec
[1] "2022-01-01" "2022-01-02" "2022-01-03" "2022-01-04" "2022-01-05"
> class(datevec)
[1] "Date"
>
> mod_datevec = ifelse(datevec < as.Date("2022-01-03"), datevec, as.Date("2022-02-01"))
> mod_datevec
[1] 18993 18994 19024 19024 19024
> class(mod_datevec)
[1] "numeric"

我们发现日期已经变成了数字。 ifelse() 函数在日期和因子变量上无法按预期工作。

现在让我们看看 dplyr 包提供的解决方案。


R中dplyr包的 if_else() 函数

dplyr 包中的 if_else() 函数解决了一些与基础 R 的 ifelse() 函数相关的问题。

  • 它确保 value_if_truevalue_if_false 是同一类型。
  • 它从 value_if_true 中获取所有其他属性。

让我们以这个函数为例。

# 首先加载 dplyr 包。
library(dplyr)

# 从这两个向量创建另一个数据框。
dplyr_df = data.frame(Col1, Col2)

# U使用向量化的 if_else() 函数。
dplyr_df$NewCol = if_else(Col1 == "B", "Col1 was B", "F")

# 查看结果
dplyr_df

我们可以检查输出并看到该函数按预期工作,就像 base R 的 ifelse() 一样。

它如何在日期上工作? 让我们检查一下。

# 基于先前创建的向量,使用 if_else() 创建一个新向量。 查看它。
dplyr_datevec = if_else(datevec < as.Date("2022-01-03"), datevec, as.Date(NA))
dplyr_datevec

输出结果

> dplyr_datevec = if_else(datevec < as.Date("2022-01-03"), datevec, as.Date(NA))
> dplyr_datevec
[1] "2022-01-01" "2022-01-02" NA           NA           NA

我们发现 dplyr 和 if_else() 函数在日期上可以正常工作。


在 R 中的 if_else() 函数中使用多个条件

我们可以使用向量化的 &| 组合多个条件 运算符,代表 AND 和 OR。

这些可以在 ifelse()if_else() 中使用。 在我们的示例中,我们将使用 if_else() 因为它更好。

# 从相同的两个向量创建数据框。
mult_df = data.frame(Col1, Col2)

# 基于多个条件结合AND创建新列,使用&。
mult_df$AND_Col = if_else((Col1 == "A" & Col2 == "y"), "AND", "F")

# 查看包含添加列的数据框。
mult_df

# 根据多个条件结合 Or 创建另一列,使用 |。
mult_df$OR_Col = if_else((Col1 == "A" | Col2 == "y"), "OR", "F")

# 查看包含添加列的数据框。
mult_df

最后一条命令的输出:

> mult_df
  Col1 Col2 AND_Col OR_Col
1    A    x       F     OR
2    A    x       F     OR
3    B    x       F      F
4    B    x       F      F
5    A    y     AND     OR
6    A    y     AND     OR
7    B    y       F     OR
8    B    y       F     OR

请记住,R 具有 AND 和 OR 运算符的矢量化和非矢量化版本。 我们使用矢量化的 &| 运算符来组合两个条件,因为我们想测试每一行的条件。

&| 被矢量化; &&|| 是非矢量化的。

参考和帮助:

在 R Studio 中,有关 if 语句、ifelse() 函数或 if_else() 函数的更多信息,请单击“帮助”>“搜索 R 帮助”,然后在搜索框中键入语句/函数名称(不带括号)。

或者,在 R 控制台的命令提示符处键入一个问号,后跟语句/函数名称。


结论

使用单个变量的语句、函数和运算符可能不适用于数据框。 我们需要为任务使用合适的工具。

为了有条件地创建/更新数据框的列,我们使用了向量化的 ifelse() 函数及其更好的 dplyr 版本 if_else()

我们使用向量化的 AND 和 OR 运算符来组合多个条件,&|

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

Do you understand JavaScript closures?

发布时间:2025/02/21 浏览次数:108 分类:JavaScript

The function of a closure can be inferred from its name, suggesting that it is related to the concept of scope. A closure itself is a core concept in JavaScript, and being a core concept, it is naturally also a difficult one.

Do you know about the hidden traps in variables in JavaScript?

发布时间:2025/02/21 浏览次数:178 分类:JavaScript

Whether you're just starting to learn JavaScript or have been using it for a long time, I believe you'll encounter some traps related to JavaScript variable scope. The goal is to identify these traps before you fall into them, in order to av

How much do you know about the Prototype Chain?

发布时间:2025/02/21 浏览次数:150 分类:JavaScript

The prototype chain can be considered one of the core features of JavaScript, and certainly one of its more challenging aspects. If you've learned other object-oriented programming languages, you may find it somewhat confusing when you start

Solution for Flickering During Vue Template Parsing

发布时间:2025/02/21 浏览次数:103 分类:Vue

Solution for Flickering During Vue Template Parsing, Recently, while working on a project, I noticed that when the internet speed is slow, the screen flickers and the expression message appears. This happens because when the internet speed i

Pandas read_csv()函数

发布时间:2024/04/24 浏览次数:254 分类:Python

Pandas read_csv()函数将指定的逗号分隔值(csv)文件读取到 DataFrame 中。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便