繁体   English   中英

在多个变量中使用 case_when/if_any 创建变量

[英]create variable with case_when/if_any across multiple variables

我有一个数据集,其中包含与每个月对应的一些变量的名称(例如 var1_M1、var1_M2 var2_M1 ...),我需要按每个月(在有条件之后)进行总结,并在找到值 > 90 时识别第一个案例,最后指出对应的月份。

library(dplyr)

ID <- c("Dave", "Joe", "Steve")
var1_M1 <- c(10, 10, 90)
var1_M2 <- c(30, 90, 95)
var1_M3 <- c(90, 100, 95)
var2_M1 <- c(10, 90, 20)
var2_M2 <- c(33, 10, 100)
var2_M3 <- c(90, 10, 50)

data <- tibble(ID, var1_M1, var1_M2, var1_M3, var2_M1, var2_M2, var2_M3)

# A tibble: 3 x 7
  ID    var1_M1 var1_M2 var1_M3 var2_M1 var2_M2 var2_M3
  <chr>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
1 Dave       10      30      90      10      33      90
2 Joe        10      90     100      90      10      10
3 Steve      90      95      95      20     100      50

data %>% 
  mutate_at(vars(matches(c("M1","M2","M3"))),
            list(~ ifelse(. > 90, .,0))) #%>% 
  #mutate() using map_dfc and if_any ??

预计 output

# A tibble: 3 x 5
  ID       M1    M2    M3 output
  <chr> <dbl> <dbl> <dbl>  <dbl>
1 Dave      0     0     0      0
2 Joe       0     0   100      3
3 Steve     0   195    95      2

我们可以使用pivot_longer重塑为“长”格式,按“ID”分组,获取值大于 90 across列的sum ,并使用output创建第一列索引值不为 0 的max.col

library(tidyr)
library(dplyr)
pivot_longer(data, cols = -ID, names_to = c(".value"), 
   names_pattern = ".*_(.*)") %>%
   group_by(ID) %>% 
   summarise(across(everything(), ~ sum(.x[.x > 90]))) %>% 
   mutate(output = max.col(across(starts_with("M")) >0, "first") * 
     if_any(starts_with("M"), ~ .x > 0))

-输出

# A tibble: 3 × 5
  ID       M1    M2    M3 output
  <chr> <dbl> <dbl> <dbl>  <int>
1 Dave      0     0     0      0
2 Joe       0     0   100      3
3 Steve     0   195    95      2

使用pivot_longer ,我们在names_pattern中指定了一个正则表达式来捕获_之后的字符作为一个组( (...) )在列名称中,即M1M2M3 )使用.* - 匹配零个或多个字符,并指定names_to as .value以便它重塑为长格式,列名称为M1M2M3结合所有var_列。

我们用sum summarise ,使用max.col找到列值大于 0 的第一个索引。在第一行,即对于 Dave id,所有值都是 0,因此max.col返回索引 1。为了要使其为 0,请与 if_any 中的 TRUE/FALSE if_anyTRUE -> 1, FALSE -> 0)。 即创建一个专栏以更好地理解它可能会更好

pivot_longer(data, cols = -ID, names_to = c(".value"), 
   names_pattern = ".*_(.*)") %>%
   group_by(ID) %>% 
   summarise(across(everything(), ~ sum(.x[.x > 90]))) %>%
   mutate(if_any_ind = if_any(starts_with("M"), ~ .x > 0),
           output_ind =max.col(across(starts_with("M")) >0, "first"),
           output = if_any_ind * output_ind)

-输出

# A tibble: 3 × 7
  ID       M1    M2    M3 if_any_ind output_ind output
  <chr> <dbl> <dbl> <dbl> <lgl>           <int>  <int>
1 Dave      0     0     0 FALSE               1      0
2 Joe       0     0   100 TRUE                3      3
3 Steve     0   195    95 TRUE                2      2

IE。 任何值 x 0 -> 0 和值 x 1 -> 1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2025 STACKOOM.COM