R 語言中具有多條件的向量 if 函式

Jesse John 2023年1月30日 2022年5月18日
  1. R 中 if 語句的限制
  2. R 中的向量化 ifelse() 函式
  3. R 中 dplyr 包的 if_else() 函式
  4. 在 R 中的 if_else() 函式中使用多個條件
  5. まとめ
R 語言中具有多條件的向量 if 函式

常見的資料分析任務是基於同一行的其他列使用一個或多個條件建立或更新資料框列。

如果我們嘗試使用 if 語句執行此操作,則僅使用第一行來測試條件,並根據該行更新整個列。

使用資料框時,我們需要適用於多行的工具和技術。本文將學習向量化的 if 函式和向量化的 ANDOR 運算子來組合多個條件。

我們將首先建立一個小的資料框來進行說明。

# 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 的長度為一的邏輯向量 ….僅使用第一個元素。

在以下示例中,我們將根據使用另一列的條件建立一列。

# Try to use the if statement.
cond_df$NewCol = if(Col1 == "B"){cond_df$NewCol = "Col1 was B"} else{cond_df$NewCol = "Col1 was not B"}

# View the result.
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() 函式,我們可以使用它來有條件地更新資料框列。

根據文件,此函式 ...返回一個與 test...具有相同形狀的值,這使其適合在資料幀上使用。

該函式的語法是:ifelse(test, value_if_true, value_if_false)。下面的程式碼說明了這個函式的使用。

# Create a new data frame using the same vectors.
vect_df = data.frame(Col1, Col2)

# Use the vectorized ifelse() function.
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() 函式引起的變化是意料之外的。
# Create and view a vector of dates.
datevec = seq(from = as.Date("2022-01-01"), to = as.Date("2022-01-05"), by = "day")
datevec
class(datevec)

# Create a new vector of dates using the ifelse() function on the previous vector. View it.
mod_datevec = ifelse(datevec < as.Date("2022-01-03"), datevec, as.Date("2022-02-01"))
mod_datevec # Not expected result.
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 獲取所有其他屬性。

讓我們以這個函式為例。

# First load the dplyr package.
library(dplyr)

# Create another data frame from the two vectors.
dplyr_df = data.frame(Col1, Col2)

# Use the vectorized if_else() function.
dplyr_df$NewCol = if_else(Col1 == "B", "Col1 was B", "F")

# view the result.
dplyr_df

我們可以檢查輸出並檢視函式是否按預期工作,就像基本 R 的 ifelse()

它在日期上是如何工作的呢?讓我們來檢查一下。

# Create a new vector using if_else() based on the vector created earlier. View it.
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

我們發現 dplyrif_else() 函式在日期上正常工作。

在 R 中的 if_else() 函式中使用多個條件

我們可以使用向量化的&|組合多個條件運算子,代表 ANDOR

這些可以在 ifelse()if_else() 中使用。在我們的示例中,我們將使用 if_else(),因為它更好。

# Create a data frame from the same two vectors.
mult_df = data.frame(Col1, Col2)

# Create a new column based on multiple conditions combined with AND, using &.
mult_df$AND_Col = if_else((Col1 == "A" & Col2 == "y"), "AND", "F")

# View the data frame with the added column.
mult_df

# Create another column based on multiple conditions combined with Or, using |.
mult_df$OR_Col = if_else((Col1 == "A" | Col2 == "y"), "OR", "F")

# View the data frame with the added column.
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 具有向量化和非向量化版本的 ANDOR 運算子。我們使用了向量化的&|運算子來組合兩個條件,因為我們想測試每一行的條件。

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

參考資料和幫助:

在 R Studio 中,有關 if 語句、ifelse() 函式或 if_else() 函式的更多資訊,請單擊 Help > Search R Help 並在搜尋框中鍵入不帶括號的語句/函式名稱。

或者,在 R 控制檯的命令提示符處鍵入一個問號,後跟語句/函式名稱。

まとめ

使用單個變數的語句、函式和運算子可能不適用於資料框。我們需要使用適當的工具來完成任務。

為了有條件地建立/更新資料框的列,我們使用了向量化的 ifelse() 函式及其更好的 dplyr 版本 if_else()

我們使用向量化的 ANDOR 運算子來組合多個條件&|

Author: Jesse John
Jesse John avatar Jesse John avatar

Jesse is passionate about data analysis and visualization. He uses the R statistical programming language for all aspects of his work.