用 NA 填充仅包含零的组

问题描述 投票:0回答:2

我获得了一些旧数据,其中包含仅包含

0
的组。我想清理这个数据集以用于教学。虽然一些
0
自然出现在我的数据中,但一个组不可能只包含
0
。这使我得出这样的结论:可以安全地用
NA
来标记此类组中的观察结果。

目标

我希望

0
应该替换为
NA
只有当整组都充满了
0

Reprex

library(dplyr)
df <- tibble(key_1 = rep(1:2, each = 4),
                 key_2 = rep(letters[1:2], each = 2, times = 2),
                 value = c(0, 0, 0, -1, 1, 2, 1, 0))
df
#> Output
# A tibble: 8 × 3
# key_1 key_2 value
# <int> <chr> <dbl>
#     1 a         0
#     1 a         0
#     1 b         0
#     1 b        -1
#     2 a         1
#     2 a         2
#     2 b         1
#     2 b         0

此数据代表了多个关键变量唯一标识每个组的情况。

  • 1a
    组,一切都是
    0
  • 2b
    组中有一个
    0

我希望

1a
充满
NA
,而例如
2b
和其他组被保留。我希望该解决方案能够在
dplyr
管道中工作,这不是强制性的,但它会很好。

所需输出

# key_1 key_2 value
# <int> <chr> <dbl>
#     1 a        NA
#     1 a        NA
#     1 b         0
#     1 b        -1
#     2 a         1
#     2 a         2
#     2 b         1
#     2 b         0

迄今为止的尝试

我尝试使用

dplyr::case_when()
,并将
value
列的正常值设置为后备。这会引发以下错误:

df |> group_by(key_1, key_2) |>
  mutate(value = case_when(sum(value != 0) == 0 ~ NA,
                           .default = value))

#> Error:
# ! `.default` must have size 1, not size 2.

如果我不指定默认值,一切都是

NA

提供一些默认虚拟值表明条件

sum(value != 0) == 0
group_by
一起正常工作。

df |> group_by(key_1, key_2) |>
  mutate(value = case_when(sum(value != 0) == 0 ~ NA,
                           .default = "default"))
#> Output
# A tibble: 8 × 3
# Groups:   key_1, key_2 [4]
# key_1 key_2 value
# <int> <chr> <chr>
#     1 a     NA
#     1 a     NA
#     1 b     default
#     1 b     default
#     2 a     default
#     2 a     default
#     2 b     default
#     2 b     default
r if-statement dplyr case na
2个回答
1
投票

您需要确保每行都有一个

NA
。 (
case_when
对于回收比基本R更严格一些。在这里,您的测试值是组的长度-1,但您想要的结果与组中的行数具有相同的长度。)

df |>
  mutate(
    value = case_when(all(value == 0) ~ rep(NA, n()), .default = value),
    .by = c(key_1, key_2)
  )
# # A tibble: 8 × 3
#   key_1 key_2 value
#   <int> <chr> <dbl>
# 1     1 a        NA
# 2     1 a        NA
# 3     1 b         0
# 4     1 b        -1
# 5     2 a         1
# 6     2 a         2
# 7     2 b         1
# 8     2 b         0

0
投票
df |>
  mutate(all_0 = all(value == 0), .by = c(key_1, key_2)) |>
  mutate(value = if_else(all_0, NA, value))
© www.soinside.com 2019 - 2024. All rights reserved.