从data.table的一列和相应的总和中进行组合

时间:2017-01-25 21:49:00

标签: r data.table

在:

URL=$(curl -i -X GET -H "Authorization: Basic token=" -H "Cache-Control: no-cache" -H "http://company url:8080/v1/organizations/wiley/environments/api-team-ci1/stats/apis?select=sum(is_error)&timeRange=01/24/2017%2002:00~01/25/2017%2006:00") 

Out(V1是组合,V2是它们的总和):

   V1  V2
1:  A 0.6
2:  B 0.3
3:  C 0.1

使用双循环来实现这一点,这似乎很慢......任何更快,数据更快,加速的方法?

脚本:

   V1  V2
1: AA 1.2
2: AB 0.9
3: AC 0.7
4: BA 0.9
5: BB 0.6
6: BC 0.4
7: CA 0.7
8: CB 0.4
9: CC 0.2

3 个答案:

答案 0 :(得分:6)

您可以使用CJ与每个列“交叉连接”:

dtIn[, lapply(.SD, function(x) 
  Reduce(if (class(x)=="character") paste0 else `+`, CJ(x,x)))]

outer相比,这有一些优势:

  • 它不涉及矩阵(从outer)强制回到矢量。
  • 不需要重复输入var名称。
  • 如果dtIn列具有名称(默认值除外),则会保留这些名称。
  • 可以相当干净地扩展(例如,CJ(x,x,x)以获得3x组合)。

在基础上,可以使用expand.grid来完成,这与CJ基本相同:

DF = data.frame(dtIn)
data.frame(lapply(DF, function(x) 
  Reduce(if (class(x)=="character") paste0 else `+`, expand.grid(x,x))))

答案 1 :(得分:5)

双循环建议在这里使用outer

dtIn[,list(outer(V1,V1,paste0),outer(V2,V2,"+"))]

#    V1  V2
# 1: AA 1.2
# 2: BA 0.9
# 3: CA 0.7
# 4: AB 0.9
# 5: BB 0.6
# 6: CB 0.4
# 7: AC 0.7
# 8: BC 0.4
# 9: CC 0.2

答案 2 :(得分:1)

可能会更快,因为它是纯数据。实现。

> library(data.table)

> aTbl = fread("A 0.6
+ B 0.3
+ C 0.1")

> aTbl[, .SD
+      ][, ind := 1
+      ][, .SD[.SD, on='ind', allow.cartesian=T]
+      ][, `:=`(V1 = sprintf('%s%s', V1, i.V1), V2 = V2 + i.V2)
+      ][order(V1)
+      ][, .(V1, V2)
+      ]
   V1  V2
1: AA 1.2
2: AB 0.9
3: AC 0.7
4: BA 0.9
5: BB 0.6
6: BC 0.4
7: CA 0.7
8: CB 0.4
9: CC 0.2
>