【问题标题】:Crossfilter and DC.js: reduce to unique numberCrossfilter 和 DC.js:减少到唯一编号
【发布时间】:2017-07-31 12:08:10
【问题描述】:

在下面的示例中,我试图通过 Respond_Id 的唯一出现来求和。例如。在这种情况下,总共应该是3"Respond_Id"258,261345

这是我的数据:

{"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},

我知道我应该为此使用 group reduce,所以我尝试了(改编自示例):

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();

但似乎不起作用。有人知道如何使它工作吗?谢谢

【问题讨论】:

  • 在我看来这应该基本上可以工作。你得到什么样的错误,你能提供一个完整的工作代码的例子吗?如果您不想自己摆弄 reducer,您可能还想将 Reductio 作为一个选项:github.com/crossfilter/…
  • 感谢您的回答。我在 valueAccessor 中记录 d 时得到的是: {"key":433,"value":{"RespondCount":1,"Respond_Ids":{"345":1}}}
  • 您需要与我们分享一个完整的示例。我猜你的维度定义和组定义是冲突的,但由于你不分享你的维度定义,我真的不能说。
  • 另外(对多个 cmets 表示抱歉),请分享您期望/希望看到的内容。有关问题示例的更多提示,请参见此处:stackoverflow.com/help/mcve
  • 感谢您的回复。我想要的结果是基于他们的 Respond_id 的响应者总数。在上面的示例中,它应该是 3。这是我的代码的一个小提琴。 jsfiddle.net/wa9oxsdg/6。谢谢!

标签: dc.js crossfilter


【解决方案1】:

根据您的 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/

【讨论】:

  • 非常感谢。你拯救了我的一天!
  • 另一个问题,如果我想在 dc/crossfilter 之外的某些计算中使用 RespondCount,如何访问它?我试过 ntotal.all().value.RespondCount 但它似乎不起作用。谢谢
  • 执行console.log(ntotal.all()),您会发现问题所在。它返回一个数组,其中每个元素都有一个.valueRespondCount。所以ntotal.all()[0].value.RespondCount 应该会给你一些东西,虽然可能不是你想要的。
  • 嗨,Ethan,我在这里有一个与此相关的问题:stackoverflow.com/questions/45585979/grouping-in-crossfilter,您可能会得到很好的帮助。谢谢
  • 请不要使用以前的问题将人们引导到新的和相对不相关的问题。如果可以的话,我会看到他们并回答:-)
猜你喜欢
  • 1970-01-01
  • 2015-05-15
  • 1970-01-01
  • 1970-01-01
  • 2018-11-02
  • 1970-01-01
  • 2016-08-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多