R:如何根据多列的因子水平减去值?

R: How to substract values depending on factor levels on multiple columns?

我有一个看起来像这样的数据框(使用 reshape2::cast 和合并):

time days treatment extrafactor1 extrafactor2 extrafactor3 animal1  animal2 animal3
10  83  control B   water   2   2   67  40
10  83  control B   water   3   50  67  39
10  83  control A   water   3   22  80  63
10  83  control A   water   2   40  40  100
10  83  treated A   water   3   40  69  92
10  83  treated A   water   1   64  56  6
10  83  treated A   water   2   90  67  52
10  83  treated B   water   2   14  36  77
10  83  treated B   water   3   41  83  55
10  83  treated B   water   1   66  31  51
11  86  control B   water   1   99  100 10
11  86  control B   water   2   23  27  22
11  86  control A   water   3   57  10  65
11  86  control A   water   1   60  2   49
11  86  control A   water   2   23  14  44
11  86  control B   water   3   97  45  20
11  86  treated B   water   2   71  15  24
11  86  treated B   water   3   49  55  63
11  86  treated A   water   3   54  88  27

我想从处理过的样本中减去对照样本中不同动物的值。当然,减法应发生在其他因素水平匹配的地方,因此“11_86_treated_A_water_3”的动物 1 值应减去“11_86_control_A_water_3”的动物 1 值,这对每个动物。我一直在用 plyr 尝试一些东西,比如

df2 <- ddply(df, .(time,days,treatment,extrafactor1,extrafactor2,extrafactor3), transform, animal1 = animal1-animal1[treatment=="control"])

但它给了我很多 NA,我确信缺少信息来充分执行我想要的东西。实际上有 100 种动物。

我的尝试是从这里改编的,但是输入变量和要执行的列更少:Easiest way to subtract associated with one factor level from values associated with all other factor levels 在这里:R ddply with multiple variables

也可以等到将 table 重塑为 ggplot 的长格式,如果这样更容易的话?

你对我有什么建议吗?

不是最优雅的,但您可以创建一个名为 group_string 的新列,它是所有不同因素的串联字符串,就像您在示例中提到的那样。但究竟是 'control' 还是 'treated' 将是最后一个参数。因此,例如

"11_86_treated_A_water_3""11_86_control_A_water_3"

你会

"11_86_A_water_3_treated""11_86_A_water_3_control"

然后你可以 运行 循环遍历所有没有 treated/control 子字符串的唯一字符串,例如一个唯一的字符串是 "11_86_A_water_3_",对于其中的每一个,从 group_string 中具有 "treated" 的行中减去 group_string 中具有 "control" 的行。

编辑: 好的,只是有另一个想法。 除治疗(时间、天数、extrafactor1、extrafactor2、extrafactor3)之外的所有因素分组,每个子组应该有两行。然后使用 diff() 计算每个子组的这两行之间的差异。