2017-07-31 41 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'應該給你一些東西,但可能不是你想要的。 –