计算每组一行与其余数据之间的差异

时间:2019-05-08 07:57:27

标签: r dataframe dplyr data.table

我有一个data.table,带有三个id组。第一组(batch1)具有固定的dx和变化的dy。第二组(batch1)和第三组(batch2)的变化dx和固定的dy

我想为每个组计算以id结尾的1行与以23等结尾的其他行之间的差。

我该怎么做?我愿意接受basedplyrdata.table解决方案。

library(data.table)
dt <- data.table(
  id = as.factor(c("batch1_dx0.0_dy-2.1_4", "batch1_dx0.0_dy0.155_3",
                   "batch1_dx0.0_dy1.23_2", "batch1_dx0.0_dy1_1", 
                   "batch1_dx-0.8_dy1.0_2", "batch1_dx0_dy1.0_1",
                   "batch1_dx1.321_dy1.0_3", "batch1_dx4.12_dy1.0_4",
                   "batch2_dx-0.8_dy1.0_2", "batch2_dx0_dy1.0_1",
                   "batch2_dx1.321_dy1.0_3", "batch2_dx4.12_dy1.0_4")),
  val1 = c(6, 2, 2, 0, 3, 1, 3, 3, 4, 5, 1),
  val2 = c(6, 4, 2, 1, 1, 1, 5, 3, 2, 8, 9),
  val3 = c(6, 3, 3, 0, 4, 2, 4, 1, 5, 7, 1))

                        id val1 val2 val3
 1:  batch1_dx0.0_dy-2.1_4    6    6    6
 2: batch1_dx0.0_dy0.155_3    2    4    3
 3:  batch1_dx0.0_dy1.23_2    2    2    3
 4:     batch1_dx0.0_dy1_1    0    1    0
 5:  batch1_dx-0.8_dy1.0_2    3    1    4
 6:     batch1_dx0_dy1.0_1    1    1    2
 7: batch1_dx1.321_dy1.0_3    3    5    4
 8:  batch1_dx4.12_dy1.0_4    3    3    1
 9:  batch2_dx-0.8_dy1.0_2    4    2    5
10:     batch2_dx0_dy1.0_1    5    8    7
11: batch2_dx1.321_dy1.0_3    1    9    1
12:  batch2_dx4.12_dy1.0_4    6    6    6

预期产量

    id  val1    val2    val3    dval1   dval2   dval3
batch1_dx0.0_dy-2.1_4   6   6   6   6   5   6
batch1_dx0.0_dy0.155_3  2   4   3   2   3   3
batch1_dx0.0_dy1.23_2   2   2   3   2   1   3
batch1_dx0.0_dy1_1  0   1   0   0   0   0
batch1_dx-0.8_dy1.0_2   3   1   4   2   0   2
batch1_dx0_dy1.0_1  1   1   2   0   0   0
batch1_dx1.321_dy1.0_3  3   5   4   2   4   2
batch1_dx4.12_dy1.0_4   3   3   1   2   2   -1
batch2_dx-0.8_dy1.0_2   4   2   5   -1  -6  -2
batch2_dx0_dy1.0_1  5   8   7   0   0   0
batch2_dx1.321_dy1.0_3  1   9   1   -4  1   -6
batch2_dx4.12_dy1.0_4   6   6   6   1   -2  -1

enter image description here

1 个答案:

答案 0 :(得分:2)

我们首先从每个id中提取最后一个数字部分。 (ind)。然后,我们为第4行和starts_with“ val”的每一列创建组,我们从ind列中的值为1的值中减去它的值。

library(dplyr)

 dt %>%
   mutate(ind = sub(".*_(\\d+$)", "\\1", id)) %>%
   group_by(group = gl(n()/4, 4)) %>%
   mutate_at(vars(starts_with("val")), list(d = ~(. - .[ind == 1]))) %>%
   ungroup() %>%
   select(-group, -ind)



#     id                     val1  val2  val3 val1_d val2_d val3_d
#    <fct>                  <dbl> <dbl> <dbl>  <dbl>  <dbl>  <dbl>
# 1 batch1_dx0.0_dy-2.1_4      6     6     6      6      5      6
# 2 batch1_dx0.0_dy0.155_3     2     4     3      2      3      3
# 3 batch1_dx0.0_dy1.23_2      2     2     3      2      1      3
# 4 batch1_dx0.0_dy1_1         0     1     0      0      0      0
# 5 batch1_dx-0.8_dy1.0_2      3     1     4      2      0      2
# 6 batch1_dx0_dy1.0_1         1     1     2      0      0      0
# 7 batch1_dx1.321_dy1.0_3     3     5     4      2      4      2
# 8 batch1_dx4.12_dy1.0_4      3     3     1      2      2     -1
# 9 batch2_dx-0.8_dy1.0_2      4     2     5     -1     -6     -2
#10 batch2_dx0_dy1.0_1         5     8     7      0      0      0
#11 batch2_dx1.321_dy1.0_3     1     9     1     -4      1     -6
#12 batch2_dx4.12_dy1.0_4      6     6     6      1     -2     -1