在 dplyr 1.0.0 中使用 case_when 在多列上应用条件

lle*_*lls 3 r dplyr

我无法弄清楚这一点。假设我想创建一个条件变量,每当数据框中的任何行具有包含目标的列时,该条件变量都会返回命中。

用例子来说明总是更容易。这是玩具数据

set.seed(10)
d <- data.frame(a = sample(x = letters[1:2], 
                           size = 10,
                           replace = T),
                b = sample(x = letters[1:2], 
                           size = 10,
                           replace = T),
                c = sample(x = letters[1:2], 
                           size = 10,
                           replace = T))

d

# output
#    a b c
# 1  a a a
# 2  a b b
# 3  b a b
# 4  b a a
# 5  b b b
# 6  a a a
# 7  b b a
# 8  b b b
# 9  a b b
# 10 a a a
Run Code Online (Sandbox Code Playgroud)

现在我想创建一个列,当任何行中anyA有一个时返回,当不存在时返回。输出看起来像这样anoAa

#    a b c anyA
# 1  a a a anyA
# 2  a b b anyA
# 3  b a b anyA
# 4  b a a anyA
# 5  b b b  noA
# 6  a a a anyA
# 7  b b a anyA
# 8  b b b  noA
# 9  a b b anyA
# 10 a a a anyA
Run Code Online (Sandbox Code Playgroud)

我尝试了以下代码,使用、mutate、rowwise、c_across 和 case_when

d %>%
  rowwise() %>%
    mutate(anyA = case_when(c_across(cols = everything(),
                            any(.x == "a") ~ "anyA",
                            TRUE ~ "noA")))
Run Code Online (Sandbox Code Playgroud)

但这没有用。我真的不知道自己在做什么。有任何想法吗?

ps 我特别不想命名 中的所有列case_when。在我的实际示例中,有很多列需​​要应用条件。

Ron*_*hah 5

您可以使用rowwiseandc_across作为 -

library(dplyr)

d %>%
  rowwise() %>%
  mutate(anyA = case_when(any(c_across() == "a") ~ "anyA",
                              TRUE ~ "noA")) %>%
  ungroup

#   a     b     c     anyA 
#   <chr> <chr> <chr> <chr>
# 1 a     a     a     anyA 
# 2 a     b     b     anyA 
# 3 b     a     b     anyA 
# 4 b     a     a     anyA 
# 5 b     b     b     noA  
# 6 a     a     a     anyA 
# 7 b     b     a     anyA 
# 8 b     b     b     noA  
# 9 a     b     b     anyA 
#10 a     a     a     anyA 
Run Code Online (Sandbox Code Playgroud)

c_across()默认情况下有cols = everything().


或者不使用rowwise,使用if_any它应该更快。

d %>% mutate(anyA = if_else(if_any(.fns = ~. == 'a'), "anyA", "noA"))
Run Code Online (Sandbox Code Playgroud)