举个例子:
> set.seed(42)
> ids <- c("u1", "u2", "u3")
> groups <- c(rep("A",3), rep("B",3), rep("C",3))
> reps <- c(rep("r1",9), rep("r2",9), rep("r3",9))
> vals <- rnorm(27, 0, 2)
>
> df = data.frame(ids = rep(ids, 9), groups = rep(groups,3), reps = reps, vals = vals)
> df
ids groups reps vals
1 u1 A r1 2.7419169
2 u2 A r1 -1.1293963
3 u3 A r1 0.7262568
4 u1 B r1 1.2657252
5 u2 B r1 0.8085366
6 u3 B r1 -0.2122490
7 u1 C r1 3.0230440
8 u2 C r1 -0.1893181
9 u3 C r1 4.0368474
10 u1 A r2 -0.1254282
11 u2 A r2 2.6097393
12 u3 A r2 4.5732908
13 u1 B r2 -2.7777214
14 u2 B r2 -0.5575775
15 u3 B r2 -0.2666427
16 u1 C r2 1.2719008
17 u2 C r2 -0.5685058
18 u3 C r2 -5.3129108
19 u1 A r3 -4.8809339
20 u2 A r3 2.6402267
21 u3 A r3 -0.6132772
22 u1 B r3 -3.5626169
23 u2 B r3 -0.3438347
24 u3 B r3 2.4293494
25 u1 C r3 3.7903869
26 u2 C r3 -0.8609383
27 u3 C r3 -0.5145388
我想要做的是为每个 id 减去 C.r1、C.r2 和 C.r3 中值的平均值。这个想法是使用 C 组作为其他组的基线。
因此,就预期结果而言,对于前两行:
0.046
-0.69
我怎样才能让它在一个大(大约 100 万行)表中的所有行上工作,除了这里的相关列之外,它还包含许多其他列?我显然需要按
ids
分组,但是查找与 group == C
特定匹配的值以及 vals 的平均值有点棘手。> dt <- setDT(df)
> dt[groups == "C", cmean := mean(vals), ids]
为我提供了每个 id(在多个副本中)的 C 组测量方法,但我无法立即使用这些值,因为所有其他行都已被过滤掉。我想我可能需要以某种方式链接,但我不确定具体是如何链接的。
我对
data.table
和 dplyr
的解决方案同样感兴趣 最佳答案
我们可以在对'C'的'groups'进行子集化后进行join,按'ids'分组,得到'vals'的mean
,然后我们将原始数据集on
加入'ids',从'vals'中减去'vals'第一个数据集带有来自第二个的 'Meanvals' 并将( :=
)它分配给 'newvals'
setDT(df)[df[groups=="C", .(Meanvals = mean(vals)), ids],
newvals := vals - Meanvals, on = .(ids)]
head(df)
关于r - 如何根据同一列但不同行的值更新列中的值?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43848511/