关于 d3.js:crossfilter – 计算具有属性的所有记录的百分比

crossfilter - calculating percent of all records with a property

这是我的问题:

我正在使用从 mongo db 获取 json 数据的 python Flask服务器,并在其中指定要导入的字段。此数据为 json 格式,并且仅以这种方式获取。一旦通过graphs.js中的交叉过滤器,是否可以对这些字段进行转换?例如我有一个状态属性,它可以取值 "Pass"、"In Progress"、"on Hold" 或 "Fail"。我基本上想做一个指标来告诉我失败百分比。所以理想情况下,我必须对数据进行一些计算。请就此提出建议。

1
2
3
4
5
6
7
8
Sample data (in tabular form for clarity) looks like:
TrialLocation     | Subject Status
Site A            | In progress
Site A            | Pass
Site B            | In progress
Site A            | In progress
Site B            | On Hold
Site A            | Screen Failure

在这种情况下,我应该在 x 轴和 y 轴上获得一个带有站点名称的条形图,我应该获得计算失败百分比的指标。在这种情况下是
站点 A 为 25%,站点 B 为 0%。

所以我首先创建了图表,它给了我每个站点的主题数。

1
2
3
var siteName = ndx.dimension(function(d) { return d["TrialLocation"];});
var numSubjectsBySite = siteName.group();
var siteLevelChart = dc.barChart("#site-level-count","subjectView");

最后是图表:

1
2
3
4
5
6
7
siteLevelChart
 .width(2000)
 .height(200)
 .transitionDuration(1000)
 .dimension(siteName)
 .group(numSubjectsBySite)
 .ordering(function(d){return d.value;})

所以我想,我会用 SubjectStatus = "Screen Failure" 计算行数,然后除以总行数,在这种情况下是 "numSubjectsBySite" 变量
然后当我介绍这段代码时:

1
2
var countScreenFailures = ndx.dimension(function(d){ return d["SubjectStatus"];});
 countScreenFailures.filter("Off Study");

我的条形图只显示 Subject Status ="ScreenFailure" 的行。

如何计算屏幕故障率然后使用它?请帮帮我?

非常感谢。
安莫尔


您需要构建自定义分组/归约函数来跟踪每个状态的计数以及总计数。然后你可以在图表中除以计算你的百分比。如果您对使用 Reductio 感兴趣,您可能可以执行以下操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var reducer = reductio().count(true);

// Do this as many times as you need for different status counts. Each
// call of reducer.value will add a new property to your groups where
// you can store the count for that status.
reducer.value("ScreenFailure").sum(
  function(d) {
    // This counts records with SubjectStatus ="Screen Failure"
    return d["SubjectStatus"] ==="Screen Failure" ? 1 : 0;
  });

// Build the group with the Reductio reducers.
var numSubjectsBySite = reducer(siteName.group());

// In your dc.js chart, calculate the % using a value accessor.
siteLevelChart
 .width(2000)
 .height(200)
 .transitionDuration(1000)
 .dimension(siteName)
 .group(numSubjectsBySite)
 .valueAccessor(function(p) { return p.value.ScreenFailure.sum / p.value.count; })
 .ordering(function(d){return d.value;})


您可以为此使用自定义 groupAll。这是一个直接的交叉过滤器解决方案,基于您在后面的问题中提供的 jsfiddle。

(用小提琴来回答要容易得多!)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var all = ndx.groupAll();
var failurePercentGroup = all.reduce(
    function(p, v) {
        ++p.count;
        p.failures += (v.Status === 'Screen Failure' ? 1 : 0);
        p.failPercent = p.count ? p.failures/p.count : 0;
        return p;
    },
    function(p, v) {
        --p.count;
        p.failures -= (v.Status === 'Screen Failure' ? 1 : 0);
        p.failPercent = p.count ? p.failures/p.count : 0;
        return p;
    },
    function() {
        return {
            count: 0,
            failures: 0,
            failPercent: 0
        };
    }
);

failurePercent.valueAccessor(function (x) {
    return x.failPercent;
})
    .group(failurePercentGroup);

@Ethan 的回答看起来应该可以工作,但是您在其他地方说您无法让它工作。

在这里更新小提琴:http://jsfiddle.net/gordonwoodhull/vct0dzou/8/

我没有将它格式化为百分比,所以它只是显示一个比率,但你应该能够弄清楚那部分。