2015-07-28 3 views
2

CrossFilter/JS новичок здесь.Количество уникальных значений с использованием CrossFilter

Этот вопрос в значительной степени описывает именно то, что я пытаюсь сделать, но не кажется, что будет решение с использованием CrossFilter:

How to return the number of unique values by category using crossfilter?

У меня есть данные с

var va = [{ 
date: "2014-10-01", 
id: "1"}, 
{ 
date: "2014-10-02", 
id: "1"}, 
{ 
date: "2014-10-03", 
id: "1"}, 
{ 
date: "2014-10-04", 
id: "1"}, 
{ 
date: "2014-10-05", 
id: "1"}, 
{ 
date: "2014-10-01", 
id: "2"}, 
{ 
date: "2014-10-02", 
id: "2"}, 
{ 
date: "2014-10-03", 
id: "2"}, 
{ 
date: "2014-10-04", 
id: "1"}, 
{ 
date: "2014-10-01", 
id: "3"}, 
{ 
date: "2014-10-02", 
id: "3"}, 
{ 
date: "2014-10-03", 
id: "1"}, 
{ 
date: "2014-10-01", 
id: "4"}, 
{ 
date: "2014-10-02", 
id: "1"}, 
{ 
date: "2014-10-01", 
id: "5"} 
} 

Я пытаюсь получить от этого число уникальных идентификаторов в день. Я хотел бы, чтобы сгруппировать по дате и в основном имеют количество уникальных идентификаторов для этой конкретной даты:

"2014-10-01" - 5 
"2014-10-02" - 3 
"2014-10-03" - 2 
"2014-10-04" - 1 
"2014-10-05" - 1 

В настоящее время я пытаюсь следовать ответ, данный в этом вопросе

Crossfilter reduce :: find number of uniques

сделать следующее:

//Create a Crossfilter instance 
var ndx = crossfilter(va); 

//Define dimensions 
var date_dim = ndx.dimension(function(d) { 
    return d["date"]; }); 

//total number of ids per date 
var num_ids_by_date = date_dim.group(); 

//unique number of ids per date 
var num_uniq_ids_by_date = date_dim 
    .group() 
    .reduce(
     function (p, d) { 
      if(d.id in p.ids){ 
      } 
      else{ 
       p.ids[d.id] = 1; 
      } 
      return p; 
     }, 

     function (p, d) { 
      p.ids[d.id]--; 
      if(p.ids[d.id] === 0){ 
       delete p.ids[d.id]; 
      } 
      return p; 
     }, 

     function() { 
      return {ids: {}}; 
     }) 

Когда я смотрю в num_uniq_ids_by_date объекта и вызвать num_uniq_ids_by_date.reduceCount().top(1), это, кажется, такой же выход, как num_ids_by_date.top(1).

Так что, похоже, я все еще не получаю то, что искал, и некоторое время был в тупике.

Любые предложения? Заранее спасибо!

+0

Похоже, вы не увеличиваете счетчик на добавление, что вызовет проблемы. Если вы соберете рабочий пример, будет легче диагностировать проблему. Вы также можете использовать библиотеку, такую ​​как Reductio, которая поддерживает это: https://github.com/esjewett/reductio#aggregations-standard-aggregations-exception-aggregation (подключая мою собственную библиотеку, извините) –

+0

Спасибо за ответ Этан. Причина, по которой я не увеличиваю счетчик при добавлении, состоит в том, что я не полностью забочусь о количестве каждого конкретного идентификатора, я просто хотел бы количество уникальных идентификаторов. Кроме того, спасибо за предложение библиотеки, я обязательно проверю это. Если возможно, я хотел бы сохранить его только в библиотеке CrossFilter, пока я все еще участвую :) – archeezee

+0

Если вы не увеличиваете на add, но вы уменьшаете на удалении (что вы делаете), вы очень быстро попадаю в непоследовательное состояние. Однако я не видел вашего фактического вопроса. Вызов 'num_uniq_ids_by_date.reduceCount()' уничтожает все ваши пользовательские редукторы. Просто вызовите 'num_uniq_ids_by_date.top (1)'. –

ответ

1

Хорошо, я смог его получить.

То, что я в конечном итоге делает это следующим образом:

//Create a Crossfilter instance 
var ndx = crossfilter(va); 

//Define dimensions 
var date_dim = ndx.dimension(function(d) { 
    return d["date"]; }); 

var num_unique_ids_by_date = date_dim 
    .group() 
    .reduce(
     function (p, d) { 
      if(d.id in p.ids){ 
       p.ids[d.id] += 1 
      } 
      else{ 
       p.ids[d.id] = 1; 
       p.id_count++; 
      } 
      return p; 
     }, 

     function (p, d) { 
      p.ids[d.id]--; 
      if(p.ids[d.id] === 0){ 
       delete p.ids[d.id]; 
       p.id_count--; 
      } 
      return p; 
     }, 

     function() { 
       return {ids: {}, 
       id_count: 0}; 
      }); 

Это дает мне общее число уникальных идентификаторов, а также общее NUMER вхождений каждого идентификатора.

Затем, когда я хочу отобразить это на моей гистограмме с помощью dc.js, я продолжаю использовать следующий код.

var minDate = date_dim.bottom(1)[0]["date"]; 
var maxDate = date_dim.top(1)[0]["date"]; 

var timeChart = dc.barChart("#time-chart"); 

timeChart 
    .width(1500) 
    .height(400) 
    .margins({top: 10, right: 50, bottom: 30, left: 50}) 
    .dimension(date_dim) 
    .group(num_unique_ids_by_date) 
    .valueAccessor(function (d) { 
     return d.value.id_count; 
    }) 
    .transitionDuration(500) 
    .x(d3.time.scale().domain([minDate, maxDate])) 
    .elasticY(true) 
    .elasticX(true) 
    .xAxisLabel("Year") 
    .yAxis(); 

dc.renderAll(); 
Смежные вопросы