R dplyr条件突变与group_by



我有一个分组的data.frame,并希望有条件地改变某个列all()的列。

在这个例子中,我有一个简单的 data.frame,有 3 列;我按列code分组,如果该组的列B完全是NA,我想从第A列复制值,否则保留B的原始非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.

有没有办法在管道%>%链中实现我的目标?
提前感谢。

而不是ifelse使用if/else因为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 

最新更新