【问题标题】:Using case_when with dplyr across将 case_when 与 dplyr 一起使用
【发布时间】:2021-01-19 04:39:29
【问题描述】:

我正在尝试使用 dplyr 的新“跨越”函数将 mutate_at() 转换为 mutate(),但有点难过。

简而言之,我需要将一系列列中的值与“基线”列进行比较。当列中的值高于基线时,我需要使用基线值。当列中的值低于或等于基线时,我需要保留该值。这是一个示例数据集(我的实际数据集要大得多):

test <- structure(list(baseline = c(5, 7, 8, 4, 9, 1, 0, 46, 47), bob = c(7, 
11, 34, 9, 6, 8, 3, 49, 12), sally = c(3, 5, 2, 2, 6, 1, 3, 4, 
56), rita = c(6, 4, 6, 7, 6, 0, 3, 11, 3)), class = c("spec_tbl_df", 
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -9L), spec = structure(list(
    cols = list(baseline = structure(list(), class = c("collector_double", 
    "collector")), bob = structure(list(), class = c("collector_double", 
    "collector")), sally = structure(list(), class = c("collector_double", 
    "collector")), rita = structure(list(), class = c("collector_double", 
    "collector"))), default = structure(list(), class = c("collector_guess", 
    "collector")), skip = 1), class = "col_spec"))

我当前的代码使用 mutate_at() 并且工作正常:

trial1 <- test %>% 
  mutate_at(
    vars('bob','sally', 'rita'),
    funs(case_when(
      . > baseline ~ baseline, 
      . <= baseline ~ .)))

但是当我尝试更新它以反映 dplyr 1.0 中的 cross() 时,我不断收到错误消息。这是我的尝试:

trial2 <- test %>% 
  mutate(across(c(bob, sally, rita), 
                case_when(. > baseline ~ baseline, 
                          . <= baseline ~ .)))

这是错误:

错误:mutate() 输入 ..1 有问题。 x . &gt; baseline ~ baseline. &lt;= baseline ~ . 的长度必须为 36 或 1,而不是 9、4。 ℹ 输入..1across(...)

任何想法我可能做错了什么? case_when() 是否适用于cross?

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    我们可以使用~来指定匿名函数/lambda函数调用

    library(dplyr)
    test %>% 
       mutate(across(c(bob, sally, rita), 
                 ~ case_when(. > baseline ~ baseline, 
                           . <= baseline ~ .)))
    

    -输出

    # A tibble: 9 x 4
    #  baseline   bob sally  rita
    #     <dbl> <dbl> <dbl> <dbl>
    #1        5     5     3     5
    #2        7     7     5     4
    #3        8     8     2     6
    #4        4     4     2     4
    #5        9     6     6     6
    #6        1     1     1     0
    #7        0     0     0     0
    #8       46    46     4    11
    #9       47    12    47     3
    

    或使用.funs 参数

    test %>% 
            mutate(across(c(bob, sally, rita), 
                      .funs = case_when(. > baseline ~ baseline, 
                                . <= baseline ~ .)))
    

    根据?acrossfns 的参数可以是任一

    应用于每个选定列的函数。可能的值是:

    NULL,返回未转换的列。

    一个函数,例如意思。

    一个 purrr 风格的 lambda,例如〜意思(.x,na.rm = TRUE)

    函数/lambda 列表,例如list(mean = mean, n_miss = ~ sum(is.na(.x))


    另外,我们可以使用pmin,而不是case_when

    test %>% 
        mutate(across(c(bob, sally, rita), ~ pmin(baseline, .)))
    

    -输出

    # A tibble: 9 x 4
    #  baseline   bob sally  rita
    #     <dbl> <dbl> <dbl> <dbl>
    #1        5     5     3     5
    #2        7     7     5     4
    #3        8     8     2     6
    #4        4     4     2     4
    #5        9     6     6     6
    #6        1     1     1     0
    #7        0     0     0     0
    #8       46    46     4    11
    #9       47    12    47     3
    

    【讨论】:

      猜你喜欢
      • 2017-12-02
      • 2022-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-16
      • 1970-01-01
      • 2022-09-26
      • 2021-09-07
      相关资源
      最近更新 更多