3

我有两个 data.tablesmainmetrics,两者都由cid 我想将main位于度量中的几个值中的每一个的平均值添加到表中。

但是,我想过滤code,只metrics用给定的code.

> 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")

这些行获得了所需的输出,但我很难将新的 col 分配回 main。(另外,最好以编程方式进行)。

main[metrics[code==code.filters[[1]]]][,  list(mean(c(value1))), by=cid]
main[metrics[code==code.filters[[1]]]][,  list(mean(c(value2))), by=cid]
main[metrics[code==code.filters[[2]]]][,  list(mean(c(value1))), by=cid]
main[metrics[code==code.filters[[1]]]][,  list(mean(c(value2))), by=cid]

此外,有人可以解释为什么以下行只取每组中的最后一个值吗?

main[metrics[ code=="A"],  A.avg.val1 := mean(c(value1))]
4

3 回答 3

3

你不需要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

如果您仍想使用以下方法进行子集化main

main <- data.table(cid = c(1001:1002))
> tmp.dt[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
于 2013-01-24T20:48:57.537 回答
2

我会分两步完成。首先,得到你的手段,然后reshape是数据

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)

但实际上,我可能会将数据保留为“长”格式,因为我发现它更容易使用!

于 2013-01-24T20:49:27.783 回答
2

根据@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
于 2013-01-24T21:04:27.053 回答