首页 > 解决方案 > 如何使用 dplyr 按组减去值(减去存储为一组的空白)?

问题描述

我有一些整洁的数据,其中一个是空白的:

df <- data.frame(Group = c(rep(LETTERS[1:3], 3), "Blank", "Blank", "Blank"), 
                 ID = rep(1:3, 4),
                 Value = c(10, 11, 12, 21, 22, 23, 31, 32, 33, 1, 2, 3))    
df
   Group ID Value
1      A  1    10
2      B  2    11
3      C  3    12
4      A  1    21
5      B  2    22
6      C  3    23
7      A  1    31
8      B  2    32
9      C  3    33
10 Blank  1     1
11 Blank  2     2
12 Blank  3     3

我想Blank从每组(A,B,C)中减去,所以标准化数据将如下所示:

df_normalized<- data.frame(Group = rep(LETTERS[1:3], 3),
             ID = rep(1:3, 3),
             Value = c(9, 9, 9, 20, 20, 20, 30, 30, 30))

df_normalized
  Group ID Value
1     A  1     9
2     B  2     9
3     C  3     9
4     A  1    20
5     B  2    20
6     C  3    20
7     A  1    30
8     B  2    30
9     C  3    30

如何使用 dplyr 很好地做到这一点?

编辑:如何为多个组做到这一点?例如:

df <- data.frame(Cluster = c(rep("C1", 12), rep("C2", 12)),
                 Group = rep(c(rep(LETTERS[1:3], 3), "Blank", "Blank", "Blank"), 2), 
                 ID = rep(1:3, 8),
                 Value = sample(24))

标签: rtransformtidyversedplyr

解决方案


假设您只有一个“空白”值,ID如示例中所示,您可以这样做

library(dplyr)

df %>%
  group_by(ID) %>%
  mutate(Value = Value - Value[Group == "Blank"])  %>%
  filter(Group != "Blank")

#  Group    ID Value
#  <fct> <int> <dbl>
#1 A         1     9
#2 B         2     9
#3 C         3     9
#4 A         1    20
#5 B         2    20
#6 C         3    20
#7 A         1    30
#8 B         2    30
#9 C         3    30

如果您有多个“空白”,您可以使用match它来确保只选择第一个值。

df %>%
  group_by(ID) %>%
  mutate(Value = Value - Value[match("Blank", Group)])  %>%
  filter(Group != "Blank")

推荐阅读