按组内中位数分类

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

让我们假设如下数据

ID  Quantity    Group     Indicator
1   0.93        Red       1
2   0.17        Red       1
3   0.01        Red       0
4   0.44        Red       1
5   0.01        Red       0
6   0.86        Red       1
7   0.07        Red       1
8   0.02        Red       0   
9   1.00        Red       1
1   0.65        Blue      1
2   0.17        Blue      1
3   0.02        Blue      0
4   0.01        Blue      0
5   0.09        Blue      1
6   0.86        Blue      1
7   0.05        Blue      0
8   0.23        Blue      1
9   0.01        Blue      0

现在我想创建一个包含三个值/类别的新列。

  • 如果指标列值为 0,则为 1
  • 3 如果指标列值为 1 并且数量列中的值等于或高于中位数(指标 ==1 的所有值的数量中位数)。
  • 2 如果指标列值为 1 并且数量列中的值等于或低于中位数(指标 ==1 的所有值的数量中位数)。

此逻辑将单独应用于组中的值。

期待这样的输出。

数量中所有值的中位数,其中红色组的指标 == 1。 中位数(0.93, 0.17,0.44,0.86,0.07,1.00) = 0.65

蓝色组的指标 == 1 的数量中所有值的中位数。 中位数(0.65, 0.17,0.09,0.86,0.23) = 0.23

ID  Quantity    Group     Indicator   Results
1   0.93        Red       1           3   <- Above the median(0.65) for all values in red where Indicator ==1
2   0.17        Red       1           2   <- Below the median(0.65) for all values in red where Indicator ==1
3   0.01        Red       0           1
4   0.44        Red       1           2   <- Below the median(0.65) for all values in red where Indicator ==1
5   0.01        Red       0           1
6   0.86        Red       1           3   <- Above the median(0.65) for all values in red where Indicator ==1
7   0.07        Red       1           2   <- Below the median(0.65) for all values in red where Indicator ==1
8   0.02        Red       0           1
9   1.00        Red       1           3   <- Above the median(0.65) for all values in red where Indicator ==1

1   0.65        Blue      1           3
2   0.17        Blue      1           2
3   0.02        Blue      0           1
4   0.01        Blue      0           1
5   0.09        Blue      1           2
6   0.86        Blue      1           3
7   0.05        Blue      0           1
8   0.23        Blue      1           2
9   0.01        Blue      0           1 

我已经用一堆 ifelse 尝试过这个,但非常笨拙。使用 case_when 寻找有效的方法。预先感谢。

r dataframe dplyr case
2个回答
2
投票

实现您想要的结果的

dplyr
方法可能如下所示:

library(dplyr, warn = FALSE)

dat |> 
  mutate(
    Results = case_when(
      Indicator == 0 ~ 1,
     Quantity <= median(Quantity) ~ 2,
     .default = 3
    ),
    .by = c(Group, Indicator)
  )
#>    ID Quantity Group Indicator Results
#> 1   1     0.93   Red         1       3
#> 2   2     0.17   Red         1       2
#> 3   3     0.01   Red         0       1
#> 4   4     0.44   Red         1       2
#> 5   5     0.01   Red         0       1
#> 6   6     0.86   Red         1       3
#> 7   7     0.07   Red         1       2
#> 8   8     0.02   Red         0       1
#> 9   9     1.00   Red         1       3
#> 10  1     0.65  Blue         1       3
#> 11  2     0.17  Blue         1       2
#> 12  3     0.02  Blue         0       1
#> 13  4     0.01  Blue         0       1
#> 14  5     0.09  Blue         1       2
#> 15  6     0.86  Blue         1       3
#> 16  7     0.05  Blue         0       1
#> 17  8     0.23  Blue         1       2
#> 18  9     0.01  Blue         0       1

数据

dat <- data.frame(
  ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9),
  Quantity = c(0.93, 0.17, 0.01, 0.44, 0.01, 0.86, 0.07, 0.02, 1.00, 0.65, 0.17, 0.02, 0.01, 0.09, 0.86, 0.05, 0.23, 0.01),
  Group = c("Red", "Red", "Red", "Red", "Red", "Red", "Red", "Red", "Red", "Blue", "Blue", "Blue", "Blue", "Blue", "Blue", "Blue", "Blue", "Blue"),
  Indicator = c(1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0)
)

0
投票

另一种选择:

library(dplyr)

df %>%
  mutate(Results = Indicator * (1 + (Quantity > median(Quantity))) + 1,
         .by = c(Group, Indicator))

#    ID Quantity Group Indicator Results
# 1   1     0.93   Red         1       3
# 2   2     0.17   Red         1       2
# 3   3     0.01   Red         0       1
# 4   4     0.44   Red         1       2
# 5   5     0.01   Red         0       1
# 6   6     0.86   Red         1       3
# 7   7     0.07   Red         1       2
# 8   8     0.02   Red         0       1
# 9   9     1.00   Red         1       3
# 10  1     0.65  Blue         1       3
# 11  2     0.17  Blue         1       2
# 12  3     0.02  Blue         0       1
# 13  4     0.01  Blue         0       1
# 14  5     0.09  Blue         1       2
# 15  6     0.86  Blue         1       3
# 16  7     0.05  Blue         0       1
# 17  8     0.23  Blue         1       2
# 18  9     0.01  Blue         0       1
© www.soinside.com 2019 - 2024. All rights reserved.