带向量的双for循环的data.table版本

带向量的双for循环的data.table版本,r,data.table,R,Data.table,有时我想使用一个双for循环,对矩阵中的列进行索引,计算它们之间的一些值,然后分配给矩阵中的一个单元格。相关表就是一个例子。我想知道在data.table语法中是否/如何做到这一点。下面是一个for循环的示例。如何在*data.table**中执行相同的操作?即使速度较慢,也可以执行更多操作,尽管速度越快越好。请注意,我们不能假设值计算机将给出一个对称矩阵(即,y[i,j]!=y[j,i]) cos_sim这里有一种方法: x <- mtcars setDT(x) x[, lapply(

有时我想使用一个双for循环,对矩阵中的列进行索引,计算它们之间的一些值,然后分配给矩阵中的一个单元格。相关表就是一个例子。我想知道在data.table语法中是否/如何做到这一点。下面是一个for循环的示例。如何在*data.table**中执行相同的操作?即使速度较慢,也可以执行更多操作,尽管速度越快越好。请注意,我们不能假设值计算机将给出一个对称矩阵(即,
y[i,j]
!=
y[j,i]

cos_sim这里有一种方法:

x <- mtcars
setDT(x)

x[, lapply(.SD, function(xx) {
  lapply(x, function(yy) cos_sim(xx, yy))
  })]
我认为与嵌套for循环相比,它更苗条、更可取,但不确定它是否真正利用了data.table本身的特殊优势。这里有一种方法:

x <- mtcars
setDT(x)

x[, lapply(.SD, function(xx) {
  lapply(x, function(yy) cos_sim(xx, yy))
  })]

我认为与嵌套for循环相比,它更苗条、更可取,但不确定它是否真正利用了数据的特殊优势。表本身

另一种
基本R
方法是
外部

outer(x, x, FUN=Vectorize(cos_sim))
#          mpg       cyl      disp        hp      drat        wt      qsec
#mpg  1.0000000 0.8566168 0.7356738 0.7794276 0.9768897 0.8483280 0.9660715
#cyl  0.8566168 1.0000000 0.9656088 0.9689702 0.9241079 0.9828563 0.9414552
#disp 0.7356738 0.9656088 1.0000000 0.9576400 0.8266655 0.9659344 0.8599014
#hp   0.7794276 0.9689702 0.9576400 1.0000000 0.8717482 0.9492708 0.8750691
#drat 0.9768897 0.9241079 0.8266655 0.8717482 1.0000000 0.9183274 0.9859895
#wt   0.8483280 0.9828563 0.9659344 0.9492708 0.9183274 1.0000000 0.9484697
#qsec 0.9660715 0.9414552 0.8599014 0.8750691 0.9859895 0.9484697 1.0000000
#vs   0.7753943 0.4700802 0.3356976 0.3742408 0.7022767 0.5143092 0.7130090
#am   0.7421732 0.5030698 0.3505303 0.5007184 0.7101727 0.4575882 0.6169362
#gear 0.9672733 0.9177938 0.8172070 0.8812034 0.9903890 0.9076279 0.9723964
#carb 0.7581483 0.9082799 0.8604485 0.9450793 0.8549106 0.8943285 0.8346877
#            vs        am      gear      carb
#mpg  0.7753943 0.7421732 0.9672733 0.7581483
#cyl  0.4700802 0.5030698 0.9177938 0.9082799
#disp 0.3356976 0.3505303 0.8172070 0.8604485
#hp   0.3742408 0.5007184 0.8812034 0.9450793
#drat 0.7022767 0.7101727 0.9903890 0.8549106
#wt   0.5143092 0.4575882 0.9076279 0.8943285
#qsec 0.7130090 0.6169362 0.9723964 0.8346877
#vs   1.0000000 0.5188745 0.6788292 0.3655971
#am   0.5188745 1.0000000 0.7435907 0.5766850
#gear 0.6788292 0.7435907 1.0000000 0.8802046
#carb 0.3655971 0.5766850 0.8802046 1.0000000
它也可以被制作成
data.table
语法,但是输出是
矩阵
,所以我不会说效率会有任何提高

setDT(x)[,outer(.SD, .SD, FUN=Vectorize(cos_sim))]

另一种
baser
方法是
outer

outer(x, x, FUN=Vectorize(cos_sim))
#          mpg       cyl      disp        hp      drat        wt      qsec
#mpg  1.0000000 0.8566168 0.7356738 0.7794276 0.9768897 0.8483280 0.9660715
#cyl  0.8566168 1.0000000 0.9656088 0.9689702 0.9241079 0.9828563 0.9414552
#disp 0.7356738 0.9656088 1.0000000 0.9576400 0.8266655 0.9659344 0.8599014
#hp   0.7794276 0.9689702 0.9576400 1.0000000 0.8717482 0.9492708 0.8750691
#drat 0.9768897 0.9241079 0.8266655 0.8717482 1.0000000 0.9183274 0.9859895
#wt   0.8483280 0.9828563 0.9659344 0.9492708 0.9183274 1.0000000 0.9484697
#qsec 0.9660715 0.9414552 0.8599014 0.8750691 0.9859895 0.9484697 1.0000000
#vs   0.7753943 0.4700802 0.3356976 0.3742408 0.7022767 0.5143092 0.7130090
#am   0.7421732 0.5030698 0.3505303 0.5007184 0.7101727 0.4575882 0.6169362
#gear 0.9672733 0.9177938 0.8172070 0.8812034 0.9903890 0.9076279 0.9723964
#carb 0.7581483 0.9082799 0.8604485 0.9450793 0.8549106 0.8943285 0.8346877
#            vs        am      gear      carb
#mpg  0.7753943 0.7421732 0.9672733 0.7581483
#cyl  0.4700802 0.5030698 0.9177938 0.9082799
#disp 0.3356976 0.3505303 0.8172070 0.8604485
#hp   0.3742408 0.5007184 0.8812034 0.9450793
#drat 0.7022767 0.7101727 0.9903890 0.8549106
#wt   0.5143092 0.4575882 0.9076279 0.8943285
#qsec 0.7130090 0.6169362 0.9723964 0.8346877
#vs   1.0000000 0.5188745 0.6788292 0.3655971
#am   0.5188745 1.0000000 0.7435907 0.5766850
#gear 0.6788292 0.7435907 1.0000000 0.8802046
#carb 0.3655971 0.5766850 0.8802046 1.0000000
它也可以被制作成
data.table
语法,但是输出是
矩阵
,所以我不会说效率会有任何提高

setDT(x)[,outer(.SD, .SD, FUN=Vectorize(cos_sim))]

矩阵代数就效率而言,是的,矩阵运算是你最好的选择:

mx  <- as.matrix(x)
sx  <- 1 / sqrt( colSums(mx^2) )
res <- (t(mx) %*% mx) * (sx %*% t(sx))

在这种情况下,如果这是一个加号的话,您将返回一个data.table。

矩阵代数就效率而言,是的,矩阵运算是您的最佳选择:

mx  <- as.matrix(x)
sx  <- 1 / sqrt( colSums(mx^2) )
res <- (t(mx) %*% mx) * (sx %*% t(sx))
在这种情况下,如果这是一个加号的话,您会得到一个data.table