【问题标题】:R dplyr conditional mutate with group_byR dplyr 条件变异与 group_by
【发布时间】:2020-10-31 02:29:17
【问题描述】:

我有一个分组的 data.frame 并且想要改变一个列,有条件地检查某个列的all()

在这个例子中,我有一个包含 3 列的简单 data.frame;我按code 列分组,如果该组的B 列完全属于NA,我想复制A 列中的值,否则保留@987654327 的原始非NA 值@。

输入:

> example <- tibble::tribble(
  ~code, ~A, ~B,
  "1", 0.5, 0.7,
  "1", 0.5, 0.3,
  "1", 0.5, 0.25,
  "2", 0.2, NA,
  "2", 0.8, NA,
  "2", 0.5, NA
)
> example %>% dplyr::group_by(code)
# A tibble: 6 x 3
# Groups:   code [2]
  code      A     B
  <chr> <dbl> <dbl>
1 1       0.5  0.7 
2 1       0.5  0.3 
3 1       0.5  0.25
4 2       0.2 NA   
5 2       0.8 NA   
6 2       0.5 NA   

期望的输出:

# A tibble: 6 x 3
  code      A     B
  <chr> <dbl> <dbl>
1 1       0.5  0.7 
2 1       0.5  0.3 
3 1       0.5  0.25
4 2       0.2  0.2 
5 2       0.8  0.8 
6 2       0.5  0.5 

我尝试使用ifelse(),它可以检查all(is.na(B)),但它不会将按行归为标准行为,而只是从第一个值复制。

example %>% 
  dplyr::group_by(code) %>%
  dplyr::mutate(
    B = ifelse(all(is.na(B)), A, B)
  )
# A tibble: 6 x 3
# Groups:   code [2]
  code      A     B
  <chr> <dbl> <dbl>
1 1       0.5   0.7
2 1       0.5   0.7
3 1       0.5   0.7
4 2       0.2   0.2
5 2       0.8   0.2
6 2       0.5   0.2

归因于固定值是可以的。

example %>% 
  dplyr::group_by(code) %>%
  dplyr::mutate(
    isBna = ifelse(all(is.na(B)), 'y', 'n')
  )
# A tibble: 6 x 4
# Groups:   code [2]
  code      A     B isBna
  <chr> <dbl> <dbl> <chr>
1 1       0.5  0.7  n    
2 1       0.5  0.3  n    
3 1       0.5  0.25 n    
4 2       0.2 NA    y    
5 2       0.8 NA    y    
6 2       0.5 NA    y      

使用dplyr::if_else() 会引发错误,抱怨AB 不是固定值。

example %>% 
  dplyr::group_by(code) %>%
  dplyr::mutate(
    B = if_else(all(is.na(B)), A, B)
  )
Error: Problem with `mutate()` input `B`.
x `true` must be length 1 (length of `condition`), not 3.
ℹ Input `B` is `if_else(all(is.na(B)), A, B)`.
ℹ The error occurred in group 1: code = "1".
Run `rlang::last_error()` to see where the error occurred.     

我的真实案例错误略有不同。

# sometime like this
Error: Problem with `mutate()` input `xx`.
x `false` must be a logical vector, not a double vector.

# and sometimes like this
Error: Problem with `mutate()` input `xx`.
x `false` must be length 1 (length of `condition`), not 12.

有什么方法可以在管道链中实现我的目标%&gt;%
提前致谢。

【问题讨论】:

    标签: r dataframe if-statement dplyr tibble


    【解决方案1】:

    使用 if/else 代替 ifelse,因为 all 返回长度为 1 的输出,而 ifelse 将返回与输入长度相同的输出,因此它会循环整个组中的第一个元素。

    library(dplyr)
    
    example %>% 
      group_by(code) %>%
      mutate(B = if(all(is.na(B))) A else B))
    
    #   code    A     B
    #  <chr> <dbl> <dbl>
    #1 1       0.5  0.7 
    #2 1       0.5  0.3 
    #3 1       0.5  0.25
    #4 2       0.2  0.2 
    #5 2       0.8  0.8 
    #6 2       0.5  0.5 
    

    【讨论】:

    • 感谢您的解决方案!我觉得很有趣我怎么能忽略简单的if 声明。
    猜你喜欢
    • 2020-01-07
    • 1970-01-01
    • 1970-01-01
    • 2022-07-24
    • 2021-04-17
    • 2017-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多