【问题标题】:Applying a conditional across multiple columns using case_when in dplyr 1.0.0在 dplyr 1.0.0 中使用 case_when 跨多个列应用条件
【发布时间】:2021-09-20 06:34:19
【问题描述】:

我想不出来这个。假设我想创建一个条件变量,每当数据框中的任何行具有包含目标的列时都会返回一个命中。

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

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

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

#    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

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

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

但它没有用。我真的不知道我在做什么。有什么想法吗?

附言我特别不想命名case_when 中的所有列。在我的真实示例中,有很多列可以应用条件。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    我们可以使用vectorizedif_any

    library(dplyr)
    d %>%
        mutate(anyA = c("noA", "anyA")[1 + (if_any(everything(), `==`, "a"))])
       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
    

    【讨论】:

      【解决方案2】:

      您可以将rowwisec_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 
      

      c_across() 默认有cols = everything()


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

      d %>% mutate(anyA = if_else(if_any(.fns = ~. == 'a'), "anyA", "noA"))
      

      【讨论】:

      • 是的,当然 c_across 是在 inside any() 中的。再次感谢
      • 在这个case_when问题的答案中,TRUE这个词是做什么的?
      • case_when 中,如果任何条件不匹配,TRUE 匹配该值并指定需要执行的操作。
      猜你喜欢
      • 2021-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多