Javascript 如何在crossfilter中的平面数据中进行group.reduce
新的交叉过滤。我有一个平面数据,如下所示:Javascript 如何在crossfilter中的平面数据中进行group.reduce,javascript,mapreduce,crossfilter,dc.js,Javascript,Mapreduce,Crossfilter,Dc.js,新的交叉过滤。我有一个平面数据,如下所示: id,name,patientId,conditionId,isPrimary,age,gender,race,Status,CGI 1,M1,1,c1,Y,33,Male,White,Discharged,0 2,M2,1,c1,N,33,Male,White,Discharged,0 3,M3,1,c2,N,33,Male,White,Discharged,0 4,M4,1,c2,N,33,Male,White,Discharged,0
id,name,patientId,conditionId,isPrimary,age,gender,race,Status,CGI
1,M1,1,c1,Y,33,Male,White,Discharged,0
2,M2,1,c1,N,33,Male,White,Discharged,0
3,M3,1,c2,N,33,Male,White,Discharged,0
4,M4,1,c2,N,33,Male,White,Discharged,0
5,M5,1,c3,N,33,Male,White,Discharged,0
6,M6,1,c3,N,33,Male,White,Discharged,0
25,M1,5,c1,Y,33,Male,White,Discharged,1
26,M7,5,c2,N,33,Male,White,Discharged,1
27,M4,5,c4,N,33,Male,White,Discharged,1
28,M4,5,c1,N,33,Male,White,Discharged,1
29,M4,5,c2,N,33,Male,White,Discharged,1
30,M5,5,c4,N,33,Male,White,Discharged,1
29,M2,6,c1,Y,33,Male,White,Discharged,1
30,M2,7,c1,Y,33,Male,White,Discharged,1
我想对conditionId
进行计数,但是由于有多个记录属于由patientId
标识的同一个人,因此值c1
的计数应该是4(属于patientId
1,5,6,7),因为同一个患者可能有多个记录(例如,patientId
的1重复了6次,其中两个有c1,应该只计算一次)。我正在努力编写一个组。在conditionId
上减少,但甚至无法开始
提前感谢。这里有一种方法。在示例中,我假设第一个值是patientId
,第二个值是conditionId
。代码跟踪已经看到的分组键(将patientId
和conditionId
串联起来),并忽略它们
var countMap = [
[1, 'c1'],
[1, 'c1'],
[2, 'c1'],
[2, 'c2']
].reduce(function (r, v) {
var condition = v[1],
groupKey = v[0] + condition;
if (!r.seen[groupKey]) {
r.seen[groupKey] = true;
r.count[condition] = (r.count[condition] || 0) + 1;
}
return r;
}, {seen: {}, count: {}}).count;
countMap.c1; //2
countMap.c2; //1
我不知道crossfilter或dc.js,这就是为什么我给你一个普通的js解决方案。在crossfilter中这样做有点复杂,但解决方案与@plalx提供的类似
这是我在我的一个项目中使用的一个帮助函数。它不是完美的,并且经过了一些优化以减少字典查找,因此它不是最具可读性的。基本思想是,您需要为每个组保留一个以前看到的值字典。您只需要记住患者,因为根据您所在的组,情况已经知道在:
function reduceHelper(accessorFunction) {
var internalCount;
return {
add: function (p, v) {
if(p.unique.has(accessorFunction(v))) {
internalCount = p.unique.get(accessorFunction(v));
p.unique.set(accessorFunction(v), internalCount + 1);
} else {
p.unique.set(accessorFunction(v), 1);
++p.count;
}
return p;
},
remove: function (p, v) {
if(p.unique.has(accessorFunction(v))) {
internalCount = p.unique.get(accessorFunction(v));
if(internalCount == 1) {
p.unique.remove(accessorFunction(v));
--p.count;
} else {
p.unique.set(accessorFunction(v), internalCount - 1);
}
}
return p;
},
init: function () {
return {unique: d3.map(), count: 0};
}
};
}
您需要在数据上创建一个交叉过滤器(xfilter),然后:
var helperFunctions = reduceHelper(function(d) { return d.patientId; });
var dim = xfilter.dimension(function (d) { return d.conditionId; };
var group = dim.group()
.reduce(helperFunctions.add, helperFunctions.remove, helperFunctions.init);
现在,您的小组将统计每种情况下的患者数量。如果某个患者的情况出现不止一次,则该患者仍将只统计一次。如果我的解决方案正常工作,至少会这样:-)您希望的输出是什么?你只是想要c1的计数,还是想要一个包含每个条件计数的映射?我想要conditionId的计数,它应该是c1:4、c2:2、c3:1和c4:1。谢谢,谢谢!你是个天才!:)