2017-07-31 44 views
1

在下面的示例中,我试图通过Respond_Id的唯一出现次数进行求和。例如。在这种情况下,应该总共为3,"Respond_Id"258,261345Crossfilter和DC.js:缩小到唯一编号

这是我的数据:

{"Respond_Id":258,"Gender":"Female","Age":"18-21","Answer":424}, 
{"Respond_Id":258,"Gender":"Female","Age":"18-21","Answer":428}, 
{"Respond_Id":261,"Gender":"Male","Age":"22-26", "Answer":427}, 
{"Respond_Id":261,"Gender":"Male","Age":"22-26", "Answer":432}, 
{"Respond_Id":345,"Gender":"Female","Age":"27-30","Answer":424}, 
{"Respond_Id":345,"Gender":"Female","Age":"27-30","Answer":425}, 
{"Respond_Id":345,"Gender":"Female","Age":"27-30","Answer":433}, 

我知道我应该使用组减少对于这一点,所以我想(改编自一个例子):

var ntotal = answerDim.group().reduce(
       function(p, d) { 
        if(d.Respond_Id in p.Respond_Ids){ 
         p.Respond_Ids[d.Respond_Id]++; 
        } 
        else { 
         p.Respond_Ids[d.Respond_Id] = 1; 
         p.RespondCount++; 
        } 
        return p; 
       }, 
       function (p, d) { 
        p.Respond_Ids[d.Respond_Id]--; 
        if(p.Respond_Ids[d.Respond_Id] === 0){ 
         delete p.Respond_Ids[d.Respond_Id]; 
         p.RespondCount--; 
        } 
        return p; 
       }, 
       function() { 
        return { 
         RespondCount: 0, 
         Respond_Ids: {} 
        }; 

       } 
      ); 

然后:

numberDisplay 
     .group(ntotal) 
     .valueAccessor(function(d){ return d.value.RespondCount; }); 

    dc.renderAll(); 

但似乎不工作。有人知道如何使其工作?谢谢

+0

在我看来,这应该基本上工作。你得到了什么样的错误,你能提供一个完整的工作代码的例子吗?如果你不想自己摆弄reducer,你可能也想看看Reductio作为一个选项:https://github.com/crossfilter/reductio#aggregations-standard-aggregations-exception-aggregation –

+0

谢谢你的回答。在valueAccessor中记录d时得到的是:{“key”:433,“value”:{“RespondCount”:1,“Respond_Ids”:{“345”:1}}} – road

+0

您需要共享与我们完整的例子。我猜想你的维度定义和组定义是相互冲突的,但是因为你没有分享你的维度定义,所以我无法确定。 –

回答

0

根据您的jsfiddle,你的设置是这样的:

var RespondDim  = ndx.dimension(function (d) { return d.Respond_Id;}); 
var ntotal   = RespondDim.group().reduce(
           function(p, d) { 
            if(d.Respond_Id in p.Respond_Ids){ 
             p.Respond_Ids[d.Respond_Id]++; 
            } 
            else { 
             p.Respond_Ids[d.Respond_Id] = 1; 
             p.RespondCount++; 
            } 
            return p; 
           }, 
           function (p, d) { 
            p.Respond_Ids[d.Respond_Id]--; 
            if(p.Respond_Ids[d.Respond_Id] === 0){ 
             delete p.Respond_Ids[d.Respond_Id]; 
             p.RespondCount--; 
            } 
            return p; 
           }, 
           function() { 
            return { 
             RespondCount: 0, 
             Respond_Ids: {} 
            }; 
           }); 

什么是重要的,这里要注意的是,你的组密钥,默认情况下,是与您的维度键。所以你将有一个组每个受访者ID。这不是你想要的。

您可以切换到使用dimension.groupAll,这是专为此用例设计的,但不幸的是dimension.groupAll.reduce签名稍有不同。对你来说最简单的解决将是只定义维度有一个值:

var RespondDim  = ndx.dimension(function (d) { return true;}); 

现在你会看到ntotal.all()看起来就像这样:

{key: true, value: {RespondCount: 3, Respond_Ids: {258: 2, 261: 2, 345: 3}}} 

工作小提琴:https://jsfiddle.net/v0rdoyrt/2/

+0

非常感谢。你拯救我的一天! – road

+0

另一个问题,如果我想在dc/crossfilter之外的某些计算中使用它,我如何访问RespondCount?我试过ntotal.all()。value.RespondCount,但它似乎不工作。谢谢 – road

+0

做'console.log(ntotal.all())',你会看到问题。它返回一个数组,其中的每个元素都带有'.value'和'RespondCount'。所以'ntotal.all()[0] .value.RespondCount'应该给你一些东西,但可能不是你想要的。 –