R 如何通过因子将复杂模型输出整齐地应用于data.table

R 如何通过因子将复杂模型输出整齐地应用于data.table,r,data.table,mixture-model,R,Data.table,Mixture Model,我在R中使用normalmixEM函数(algorithim)覆盖data.table对象 在整个表中运行它是一个简单的过程。这将输出一个mixEMlist对象,其中$poster项是最感兴趣的。我可以用cbind将其映射回数据,这是一种公认的有点尴尬的方式,如下所示: library(data.table) library(ggplot2) library(mixtools) set.seed(100) faithfulDT <- data.table(faithful) faithf

我在R中使用
normalmixEM
函数(algorithim)覆盖
data.table
对象

在整个表中运行它是一个简单的过程。这将输出一个
mixEM
list对象,其中$poster项是最感兴趣的。我可以用cbind将其映射回数据,这是一种公认的有点尴尬的方式,如下所示:

library(data.table)
library(ggplot2)
library(mixtools)
set.seed(100)

faithfulDT <- data.table(faithful)
faithfulDT[, factorAB := rep(c('a', 'b'), .N)]
# Make some data

qplot(data = faithfulDT, x = eruptions, fill = factor) + facet_grid(factor ~.)
# graph the distribution

faithfulMix <- faithfulDT[, normalmixEM(eruptions)]
cbind(faithfulDT, data.table(faithfulMix$posterior)) # to join posterior probabilities to values. I'm ASSUMING this is the best way to do it?
plot(faithfulMix, whichplots = 2)
# model and graph without factorAB
显然,在这里,我已经成功地找到了一个解决方案,它似乎有正确的数字,但在很大程度上是任意的位置

在包含
factorAB
split的情况下,此工作流将整理输出,我缺少什么?显然,我需要为工作的
cbind
部分找到一个代理,但是我当前的输出一开始就很混乱。我可以提高faithfulmixAB的产量来促进这一点吗?是否可能完全跳过此操作,并直接从data.table中运行的函数中指定后验值


编辑

在@eddi和一位朋友IRL的帮助下,我现在的处境是:

faithfulDT[, mixPostFull.1 := normalmixEM(eruptions)$posterior[,1]]
faithfulDT[, mixPostFull.2 := normalmixEM(eruptions)$posterior[,2]]
它表示在不拆分因子的情况下运行模型的两个后列。以及:

faithfulDT[, mixPostAB.1 := normalmixEM(eruptions)$posterior[,1], by = factorAB]
faithfulDT[, mixPostAB.2 := normalmixEM(eruptions)$posterior[,2], by = factorAB]
它有两列,但按因子分割,这就是我要做的

我认为这两者都需要,因为后面的物体实际上是2个向量,一个表示记录在1和组中的概率,另一个表示记录在第二个组中

Eddi,你目前的答案有两列,但我认为它们与上面列出的不一致。如果有任何区别,则值略有不同:

eruptions waiting factorAB mixPostFull.1 mixPostFull.2  mixPostAB.1  mixPostAB.2
  1:     3.600      79        a  5.376906e-10  1.000000e+00 1.581467e-11 1.000000e+00
  2:     1.800      54        b  9.999998e-01  1.723648e-07 1.000000e+00 2.112761e-09
  3:     3.333      74        a  1.755506e-06  9.999982e-01 1.405098e-07 9.999999e-01
  4:     2.283      62        b  9.999406e-01  5.939085e-05 9.999974e-01 2.599843e-06
  5:     4.533      85        a  2.215050e-25  1.000000e+00 3.658846e-29 1.000000e+00
 ---                                                                                 
268:     4.117      81        b  6.337730e-18  1.000000e+00 9.658721e-10 1.000000e+00
269:     2.150      46        a  9.999912e-01  8.828998e-06 9.999828e-01 1.724380e-05
270:     4.417      90        b  3.320219e-23  1.000000e+00 1.461450e-12 1.000000e+00
271:     1.817      46        a  9.999998e-01  2.012672e-07 9.999995e-01 4.981589e-07
272:     4.467      74        b  3.912776e-24  1.000000e+00 4.818983e-13 1.000000e+00
我真正需要的是一种不必重复运行模型的方法。我很确定我可以在那里的某个地方伪造“:=”,但我现在没有时间。我会在一段时间内回到它

一段时间后
所以我在前面的文章中忽略了我不能重新运行模型来得到第二列,因为除了显然效率很低之外,由于算法的性质,除非我设置种子,因为每次运行都有不同的起点,因此,每次跑步的答案都会略有不同。

我想你是在寻找这样的答案:

faithfulDT[, {
               result = as.vector(normalmixEM(eruptions)$posterior);
               faithfulDT[, paste0('result.', factorAB) := result];
               NULL
             }
           , by = factorAB]
faithfulDT
#     eruptions waiting factorAB     result.a     result.b
#  1:     3.600      79        a 1.581719e-11 1.000000e+00
#  2:     1.800      54        b 1.405263e-07 9.999974e-01
#  3:     3.333      74        a 3.660230e-29 9.531090e-01
#  4:     2.283      62        b 5.986926e-33 3.630698e-05
#  5:     4.533      85        a 9.999983e-01 6.384911e-12
# ---                                                     
#268:     4.117      81        b 6.545978e-07 1.000000e+00
#269:     2.150      46        a 2.342451e-06 1.562445e-06
#270:     4.417      90        b 1.000000e+00 1.000000e+00
#271:     1.817      46        a 1.724380e-05 1.000000e+00
#272:     4.467      74        b 4.981589e-07 1.000000e+00

在评论和OP中进行讨论后,得出的理想答案是:

faithfulDT[, c('mixAB.1', 'mixAB.2') := as.data.table(normalmixEM(eruptions)$posterior)
           , by = factorAB]

这确实是我需要的。你能解释一下这里发生了什么事吗?我得到(现在)你指的是从顶行开始的模型后面的对象,然后它将输入第二行,这将格式化输出上的标题?第三行中的NULL代表什么?整个J参数现在是一个独立的匿名函数吗?@DaveRGP是的,整个
J表达式
是一个匿名函数,
NULL
是该函数的返回值-我们不关心返回什么,因为我们关心的主要操作是第二行中的赋值,而且
NULL
是一个不错的选择(但实际上,在第三行中输入什么并不重要)。我无法对您第二条评论中的细节进行真正的评论,因为我实际上没有研究
normalmixEM
函数的功能。我只是在OP中重写了您的表达式,以便对每个因子运行一次操作,并将每个因子的结果分配给一个新列。我注意到您在OP中添加了更多的信息-我稍后会看一看并回复。@DaveRGP您只是在寻找:
Faithfuld[,c('mixAB.1','mixAB.2'):=as.data.table(normalmixEM(爆发)$posterior),by=factorAB]
?我很难说你的最终期望结果是什么。当然,很乐意帮忙
faithfulDT[, c('mixAB.1', 'mixAB.2') := as.data.table(normalmixEM(eruptions)$posterior)
           , by = factorAB]