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

Joh*_*ith 2 r data.table

在:

   V1  V2
1:  A 0.6
2:  B 0.3
3:  C 0.1
Run Code Online (Sandbox Code Playgroud)

Out(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
Run Code Online (Sandbox Code Playgroud)

通过双循环实现这一点,这看起来很慢......任何更快,数据更快,加速的方法?

脚本:

dtIn <- data.table(LETTERS[1:3], c(0.6, 0.3, 0.1))
dtOut <- list()
for (i in 1:nrow(dtIn))
  for (j in 1:nrow(dtIn))
    dtOut[[paste0(i, j)]] <- data.table(paste0(c(dtIn[i, V1], dtIn[j, V1]), collapse = ""),
                                        dtIn[i, V2] + dtIn[j, V2])
dtOut <- rbindlist(dtOut)
Run Code Online (Sandbox Code Playgroud)

Fra*_*ank 6

您可以使用CJ"自交"连接每个列:

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

这有一些优点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))))
Run Code Online (Sandbox Code Playgroud)


ags*_*udy 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
Run Code Online (Sandbox Code Playgroud)