在SO用户提出多项建议后,我终于尝试将代码转换为使用data.table
。
library(data.table)
DT <- data.table(plate = paste0("plate",rep(1:2,each=5)),
id = rep(c("CTRL","CTRL","ID1","ID2","ID3"),2),
val = 1:10)
> DT
plate id val
1: plate1 CTRL 1
2: plate1 CTRL 2
3: plate1 ID1 3
4: plate1 ID2 4
5: plate1 ID3 5
6: plate2 CTRL 6
7: plate2 CTRL 7
8: plate2 ID1 8
9: plate2 ID2 9
10: plate2 ID3 10
我想做的是当id为“CTRL”时,按平均值DT[,val]
取平均值。
我通常会aggregate
数据框,然后使用match
将值映射回新列'ctrl'。
使用我可以获得的data.table
包:
DT[id=="CTRL",ctrl:=mean(val),by=plate]
> DT
plate id val ctrl
1: plate1 CTRL 1 1.5
2: plate1 CTRL 2 1.5
3: plate1 ID1 3 NA
4: plate1 ID2 4 NA
5: plate1 ID3 5 NA
6: plate2 CTRL 6 6.5
7: plate2 CTRL 7 6.5
8: plate2 ID1 8 NA
9: plate2 ID2 9 NA
10: plate2 ID3 10 NA
我真正需要的是:
DT <- data.table(plate = paste0("plate",rep(1:2,each=5)),
id = rep(c("CTRL","CTRL","ID1","ID2","ID3"),2),
val = 1:10,
ctrl = rep(c(1.5,6.5),each=5))
> DT
plate id val ctrl
1: plate1 CTRL 1 1.5
2: plate1 CTRL 2 1.5
3: plate1 ID1 3 1.5
4: plate1 ID2 4 1.5
5: plate1 ID3 5 1.5
6: plate2 CTRL 6 6.5
7: plate2 CTRL 7 6.5
8: plate2 ID1 8 6.5
9: plate2 ID2 9 6.5
10: plate2 ID3 10 6.5
最终我想使用更复杂的值选择,但我不知道如何选择特定值,运行某个函数,然后使用数据框将这些值映射回适当的行。
答案 0 :(得分:7)
这是你想要做的:
DT[,ctrl:=mean(val[id=="CTRL"]),by=plate]
给出了
plate id val ctrl
1: plate1 CTRL 1 1.5
2: plate1 CTRL 2 1.5
3: plate1 ID1 3 1.5
4: plate1 ID2 4 1.5
5: plate1 ID3 5 1.5
6: plate2 CTRL 6 6.5
7: plate2 CTRL 7 6.5
8: plate2 ID1 8 6.5
9: plate2 ID2 9 6.5
10: plate2 ID3 10 6.5
您的原始代码DT[id=="CTRL",ctrl:=mean(val),by=plate]
未对id=="CTRL"
不为真的行进行分配,因为当您使用[
的第一个参数时,您正在进行子集化;第二个参数中的操作仅针对子集data.table
进行。