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/
我没有将它格式化为百分比,所以它只是显示一个比率,但你应该能够弄清楚那部分。