R 连接两个data.tables后创建新列
我有两个data.tables,R 连接两个data.tables后创建新列,r,join,data.table,R,Join,Data.table,我有两个data.tables,main和metrics,都由cid 我想在表main中添加度量中几个值的平均值 但是,我想按code进行过滤,仅用给定的code对metrics中的行求平均值 > metrics cid code DZ value1 value2 1: 1001 A 101 8 21 2: 1001 B 102 11 26 3: 1001 A 103 17 25 4: 1002 A 104
main
和metrics
,都由cid
我想在表main
中添加度量中几个值的平均值
但是,我想按code
进行过滤,仅用给定的code
对metrics
中的行求平均值
> metrics
cid code DZ value1 value2
1: 1001 A 101 8 21
2: 1001 B 102 11 26
3: 1001 A 103 17 25
4: 1002 A 104 25 39
5: 1002 B 105 6 30
6: 1002 A 106 23 40
7: 1003 A 107 27 32
8: 1003 B 108 16 37
9: 1003 A 109 14 42
# DESIRED OUTPUT
> main
cid A.avg.val1 A.avg.val2 B.avg.val1 B.avg.val2
1: 1001 12.5 23.0 11 26
2: 1002 24.0 39.5 6 30
3: 1003 20.5 37.0 16 37
# SAMPLE DATA
set.seed(1)
main <- data.table(cid=1e3+1:3, key="cid")
metrics <- data.table(cid=rep(1e3+1:3, each=3), code=rep(c("A", "B", "A"), 3), DZ=101:109, value1=sample(30, 9), value2=sample(20:50, 9), key="cid")
code.filters <- c("A", "B")
另外,有人能解释一下为什么下面这行只取每组中的最后一个值吗
main[metrics[ code=="A"], A.avg.val1 := mean(c(value1))]
您不需要
main
。您可以直接从metrics
获取它,如下所示:
> tmp.dt <- metrics[, list(A.avg.val1 = mean(value1[code=="A"]),
A.avg.val2 = mean(value2[code=="A"]),
B.avg.val1 = mean(value1[code == "B"]),
B.avg.val2 = mean(value2[code == "B"])), by=cid]
# cid A.avg.val1 A.avg.val2 B.avg.val1 B.avg.val2
# 1: 1001 12.5 23.0 11 26
# 2: 1002 24.0 39.5 6 30
# 3: 1003 20.5 37.0 16 37
我会分两步来做。首先,获取您的平均值,然后对数据进行重塑
foo <- main[metrics]
bar <- foo[, list(val1 = mean(value1),
val2 = mean(value2)),
by=c('cid', 'code')]
library(reshape2)
bar.melt <- melt(bar, id.var=c('cid', 'code'))
dcast(data=bar.melt,
cid ~ code + variable)
foo根据@Arun的答案,以下内容得到了期望的结果:
invisible(
sapply(code.filters, function(cf)
main[metrics[code==cf, list(avgv1 = mean(value1), avgv2 = mean(value2)), by=cid],
paste0(cf, c(".avg.val1", ".avg.val2")) :=list(avgv1, avgv2)]
))
> main
cid A.avg.val1 A.avg.val2 B.avg.val1 B.avg.val2
1: 1001 12.5 23.0 11 26
2: 1002 24.0 39.5 6 30
3: 1003 20.5 37.0 16 37
实际上,在数据库中存储计算值不是一个好的做法。这些都应该在输出数据时进行。也许“不好的做法”是错误的术语。也许,“重点是什么”更好一些?:-)计算值的一个主要方面是它们会发生变化,所以当数据可以动态计算且始终准确时,为什么要存储这些数据呢。如果您存储并调用它,它可能已经过时且不正确。@N1tr0,我想您可能误解了这个问题:我没有将值存储回数据库,而是将其存储在data.table(即内存)中。啊,好的。这就是我在一个我不属于的地方所得到的我有更多的数据库和脚本编写经验。不是编程。我会回去玩我的沙箱。main的数据表比上面示例中的数据表大得多。我需要它返回main进行进一步计算。但是谢谢你的建议!!我想我可以在这里工作!谢谢Arun,我不认为需要tmp.dt
,因为我可以直接将您的建议包装在main[…]
中。请看下面的Hanks@Justin。我希望以一种“数据表式”的方式完成它,因为我希望获得它提供的内存效率。
foo <- main[metrics]
bar <- foo[, list(val1 = mean(value1),
val2 = mean(value2)),
by=c('cid', 'code')]
library(reshape2)
bar.melt <- melt(bar, id.var=c('cid', 'code'))
dcast(data=bar.melt,
cid ~ code + variable)
invisible(
sapply(code.filters, function(cf)
main[metrics[code==cf, list(avgv1 = mean(value1), avgv2 = mean(value2)), by=cid],
paste0(cf, c(".avg.val1", ".avg.val2")) :=list(avgv1, avgv2)]
))
> main
cid A.avg.val1 A.avg.val2 B.avg.val1 B.avg.val2
1: 1001 12.5 23.0 11 26
2: 1002 24.0 39.5 6 30
3: 1003 20.5 37.0 16 37