[英]Logical function across multiple columns using “any” function
我想在許多列中運行邏輯操作(多個條件)。 我寫了一個工作正常的查詢。 但是,我想縮短我的代碼,因為我必須編寫幾個查詢。
我嘗試使用“任何”和“括號”來縮短查詢。 但是,第二個查詢運行良好,但給了我不同的答案。 “任何”功能是否適用於多列?
這是我的條件 -
參加 | B1 | B2 | B3 | B4 | B5 | 查詢1 | 查詢2 |
---|---|---|---|---|---|---|---|
3 | -1 | -1 | -1 | -1 | -1 | 沒有任何問題 | 沒有任何問題 |
1 | -1 | 1 | -1 | -1 | 1 | 沒有任何問題 | 沒有任何問題 |
1 | -1 | -1 | -1 | -1 | -1 | 問題 | 沒有任何問題 |
2 | -1 | 1 | 1 | -1 | 1 | 沒有任何問題 | 沒有任何問題 |
2 | 1 | 1 | 1 | 1 | -1 | 沒有任何問題 | 沒有任何問題 |
1 | -99 | -99 | -99 | -99 | -99 | 沒有任何問題 | 沒有任何問題 |
如果有人幫助我減少使用不同功能的代碼行,我將不勝感激。
mutate(Batch_v1,
case_when (
((Batch_v1$B1 == 1 | Batch_v1$B2 == 1 | Batch_v1$B3 == 1 | Batch_v1$B4 == 1 | Batch_v1$B5 == 1| Batch_v1$B6 == 1| Batch_v1$B7 == 1|Batch_v1$B8 == 1|Batch_v1$B9 == 1|Batch_v1$B10 == 1|Batch_v1$BOth == 1) &
Batch_v1$Participate %in% c(1,2,-99))~"Noissue",
((Batch_v1$B1 == -99 | Batch_v1$B2 == -99 | Batch_v1$B3 == -99|Batch_v1$B4 == -99 |Batch_v1$B5 == -99|Batch_v1$B6 == -99|Batch_v1$B7 == -99|Batch_v1$B8 == 1|Batch_v1$B9 == -99|Batch_v1$B10 == -99|Batch_v1$BOth == -99) &
Batch_v1$Participate %in% c(1,2,-99))~"Noissue",
Batch_v1$Participate ==3 ~ "Noissue",
TRUE ~ "Issue"))
mutate(Batch_v1,
case_when (
((any(Batch_v1[,2:6] == 1)) & Batch_v1$Participate %in% c(1,2,-99))~ "Noissue",
((any(Batch_v1[,2:6] == -99)) & Batch_v1$Participate %in% c(1,2,-99))~ "Noissue",
Batch_v1$Participate ==3 ~ "Noissue",
TRUE ~ "Issue"))
我們可以使用across
與case_when
library(dplyr)
df %>%
mutate(across(B2:B5, ~case_when(. == 1 & B1 <=2 ~ "Noissue",
. == -99 & B1 <=2 ~ "Noissue",
B1 == 3 ~ "Noissue",
TRUE ~ "issue")
)
)
輸出:
Participate B1 B2 B3 B4 B5 Query1 Query2
<dbl> <dbl> <chr> <chr> <chr> <chr> <chr> <chr>
1 3 -1 issue issue issue issue Noissue Noissue
2 1 -1 Noissue issue issue Noissue Noissue Noissue
3 1 -1 issue issue issue issue Issue Noissue
4 2 -1 Noissue Noissue issue Noissue Noissue Noissue
5 2 1 Noissue Noissue Noissue issue Noissue Noissue
6 1 -99 Noissue Noissue Noissue Noissue Noissue Noissue
數據:
df <- structure(list(Participate = c(3, 1, 1, 2, 2, 1), B1 = c(-1,
-1, -1, -1, 1, -99), B2 = c(-1, 1, -1, 1, 1, -99), B3 = c(-1,
-1, -1, 1, 1, -99), B4 = c(-1, -1, -1, -1, 1, -99), B5 = c(-1,
1, -1, 1, -1, -99), Query1 = c("Noissue", "Noissue", "Issue",
"Noissue", "Noissue", "Noissue"), Query2 = c("Noissue", "Noissue",
"Noissue", "Noissue", "Noissue", "Noissue")), problems = structure(list(
row = 6L, col = "Query2", expected = "", actual = "embedded null",
file = "'test'"), row.names = c(NA, -1L), class = c("tbl_df",
"tbl", "data.frame")), class = c("spec_tbl_df", "tbl_df", "tbl",
"data.frame"), row.names = c(NA, -6L))
每當我們必須在許多列中按行使用邏輯條件時,通常應該考慮兩種主要方法。 這些通過lapply/map %>% Reduce/reduce
或復雜的case_when()
語句消除了對rowwise()
和Reduce()
的需要。
-1) rowSums(condition)
-2) if_any() / if_all()
這個問題最適合使用if_any()
的解決方案。
使用if_any()
Batch_v1 %>% mutate(query3 = ifelse(if_any(B2:B5, ~.x %in% c(-99, 1)) & B1<=2,
"Noissue",
"Issue"))
使用rowSums()
Batch_v1 %>% mutate(query3 = ifelse(rowSums(across(B2:B5, ~.x %in% c(-99, 1)))>0 & B1<=2,
"Noissue",
"Issue"))
輸出
# A tibble: 6 x 9
Participate B1 B2 B3 B4 B5 Query1 Query2 query3
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <chr> <chr>
1 3 -1 -1 -1 -1 -1 Noissue Noissue Issue
2 1 -1 1 -1 -1 1 Noissue Noissue Noissue
3 1 -1 -1 -1 -1 -1 Issue Noissue Issue
4 2 -1 1 1 -1 1 Noissue Noissue Noissue
5 2 1 1 1 1 -1 Noissue Noissue Noissue
6 1 -99 -99 -99 -99 -99 Noissue Noissue Noissue
這里有一些類似問題的很好的答案:
在 R和這里使用 mutate() 和 filter() 進行行邏輯運算:
R - 從數據框中刪除在數字列中僅包含零的行、基本 R 和管道友好方法?
你可以用
library(dplyr)
Batch_v1 %>%
rowwise() %>%
mutate(
Query3 = case_when(
any(B1:B5 == 1) & Participate %in% c(1,2,-99) ~ "Noissue",
any(B1:B5 == -99) & Participate %in% c(1,2,-99) ~ "Noissue",
Participate == 3 ~ "Noissue",
TRUE ~ "Issue"
)
)
返回
# A tibble: 6 x 9
# Rowwise:
Participate B1 B2 B3 B4 B5 Query1 Query2 Query3
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <chr> <chr>
1 3 -1 -1 -1 -1 -1 Noissue Noissue Noissue
2 1 -1 1 -1 -1 1 Noissue Noissue Noissue
3 1 -1 -1 -1 -1 -1 Issue Noissue Issue
4 2 -1 1 1 -1 1 Noissue Noissue Noissue
5 2 1 1 1 1 -1 Noissue Noissue Noissue
6 1 -99 -99 -99 -99 -99 Noissue Noissue Noissue
你的第二個代碼的主要問題是函數
any(Batch_v1[,2:6] == 1)
讓我們來看看
Batch_v1[,2:6] == 1
#> B1 B2 B3 B4 B5
#> [1,] FALSE FALSE FALSE FALSE FALSE
#> [2,] FALSE TRUE FALSE FALSE TRUE
#> [3,] FALSE FALSE FALSE FALSE FALSE
#> [4,] FALSE TRUE TRUE FALSE TRUE
#> [5,] TRUE TRUE TRUE TRUE FALSE
#> [6,] FALSE FALSE FALSE FALSE FALSE
所以Batch_v1[,2:6] == 1
返回一個布爾值的 data.frame。 如果此 data.frame 中的any
值為TRUE
則在此 data.frame 上應用any
將返回TRUE
。 這顯然不是您想要的行為。 使用rowwise()
強制any
應用......好吧......每行。
注意:在tidyverse
-pipe 中,如果您正在使用的當前對象上引用,則不希望使用Batch_v1$B1
。 例如, Batch_v1$B1
指的是原始Batch_v1
,沒有進行任何轉換。 在這種情況下,沒有真正的區別,但通常不應依賴於此。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.