簡體   English   中英

dplyr:filter_字符條件不起作用

[英]dplyr: filter_ with character condition not working

這是我的數據:

df <- tibble::tribble(
  ~A,  ~B,  ~C,  ~D,
  2L, "a", "e", 2L,
  4L, "a", "f", NA_integer_,
  4L, "b", "g", NA_integer_,
  4L, "b", "h", NA_integer_
  )

df$B <- as.factor(df$B) 
df$A <- as.factor(as.character(df$A)) 

這是我作為角色的過濾條件:

remove2 <- "as.integer(A)!=2L"

我只想刪除A == 2的觀察值,但是下面的代碼保留了它,為什么?

df %>% dplyr::filter_(remove2)

我想使用filter_,因為它接受條件作為字符。 如果您可以建議使用過濾器(沒有下划線版本)並以字符為條件,那也可以。

請嘗試以下操作:

remove2 <- "as.numeric(as.character(A))!=2L"

df %>% dplyr::filter_(remove2)

# A tibble: 3 x 4
  A     B     C         D
  <fct> <fct> <chr> <int>
1 4     a     f        NA
2 4     b     g        NA
3 4     b     h        NA

請注意,因子的編碼方式不同。 看到

 as.integer(df$A)
 [1] 1 2 2 2

要獲取因子“如圖所示”的值,請使用as.numeric(as.character(.))

其他答案指出,下划線功能已被棄用(盡管它們仍然有效)。 為了以絕對面向未來的方式實現這一目標,最好使用簡單的base R:

df[which(df[["A"]] != 2L),]
# A tibble: 3 x 4
  A     B     C         D
  <fct> <fct> <chr> <int>
1 4     a     f        NA
2 4     b     g        NA
3 4     b     h        NA

其他人解釋這個問題的原因,這是factor在內部編碼為整數,這可能是比它看起來像什么明顯不同。 我想指出的另一件事是filter_以來已棄用dplyr 0.7。 因此,我們可以考慮使用filter函數將字符串評估為以下兩個選項。

remove2 <- "as.integer(as.character(A)) != 2L"

library(dplyr)
library(rlang)

df %>% filter(eval(parse(text = remove2)))
# # A tibble: 3 x 4
#   A     B     C         D
#   <fct> <fct> <chr> <int>
# 1 4     a     f        NA
# 2 4     b     g        NA
# 3 4     b     h        NA

df %>% filter(eval(parse_expr(remove2)))
# # A tibble: 3 x 4
#   A     B     C         D
#   <fct> <fct> <chr> <int>
# 1 4     a     f        NA
# 2 4     b     g        NA
# 3 4     b     h        NA

代碼作為字符串是一種反模式。 這就提出了一個問題:字符串是從哪里來的?

如果是開發人員輸入您的姓名,那么編寫起來會更加困難(您無法從自動完成等IDE功能中受益),而且更容易出現錯誤(可以編寫語法上無效的代碼,不會在實際解析和評估之前被捕獲,可能要晚得多,這會導致難以理解的錯誤)。

如果是不是您的用戶輸入的,那將是一個重大的安全漏洞。

您可以改為:

remove2 <- quote(as.numeric(as.character(A)) != 2L)

filter(df, !! remove2)

!!是tidyeval框架中的“ unquote”運算符)。

盡管兩者都不盡如人意(在我看來,這仍然是代碼的味道),因為很少需要取消引用全部代碼,通常它只是一個變量名。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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