我有一个分组的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()
,它会抛出一个错误,认为A
和B
不是固定值。
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