簡體   English   中英

使用“any”函數跨多列的邏輯函數

[英]Logical function across multiple columns using “any” function

我想在許多列中運行邏輯操作(多個條件)。 我寫了一個工作正常的查詢。 但是,我想縮短我的代碼,因為我必須編寫幾個查詢。

我嘗試使用“任何”和“括號”來縮短查詢。 但是,第二個查詢運行良好,但給了我不同的答案。 “任何”功能是否適用於多列?

這是我的條件 -

  1. 任何一列(B2 到 B5)都有 1 & B1 <=2,然后是“Noissue”
  2. 任何一列(B2 到 B5)都有 -99 & B1 <=2,然后是“Noissue”
  3. B1 ==3,然后“Noissue”
  4. 休息是一切
參加 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"))

我們可以使用acrosscase_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM