Permalink
Browse files

Implemented prop.

  • Loading branch information...
1 parent cad7028 commit b107406f209673857eaa31e10da5c25e72ec126b @sethyuan committed Apr 2, 2013
Showing with 87 additions and 0 deletions.
  1. +49 −0 lib/xtabs.js
  2. +38 −0 test/xtabs.js
View
@@ -386,4 +386,53 @@ var addMargins = function(table, margins, fun) {
return Object.freeze(new Table(dim, dimnames, array));
};
+var prop = function(table, margin) {
+ var array = new Array(table.array.length);
+ if (margin == null) {
+ var total = 0;
+ for (var i = 0; i < table.array.length; i++) {
+ total += table.array[i];
+ }
+ for (var i = 0; i < array.length; i++) {
+ array[i] = table.array[i] / total;
+ }
+ } else {
+ var blockSize = margin + 1 < table.dim.length ? table.dim[margin + 1] : 1;
+ for (var i = margin + 2; i < table.dim.length; i++) {
+ blockSize *= table.dim[i];
+ }
+ var numberOfBlocks = margin - 1 >= 0 ? table.dim[margin - 1] : 1;
+ for (var i = margin - 2; i >= 0; i--) {
+ numberOfBlocks *= table.dim[i];
+ }
+ var jumpSize = 1;
+ for (var i = margin; i < table.dim.length; i++) {
+ jumpSize *= table.dim[i];
+ }
+ debugger;
+
+ var calcGroup = function(group) {
+ var sum = 0;
+ for (var i = 0; i < numberOfBlocks; i++) {
+ for (var j = 0; j < blockSize; j++) {
+ var pos = group * blockSize + i * jumpSize + j;
+ sum += table.array[pos];
+ }
+ }
+ for (var i = 0; i < numberOfBlocks; i++) {
+ for (var j = 0; j < blockSize; j++) {
+ var pos = group * blockSize + i * jumpSize + j;
+ array[pos] = table.array[pos] / sum;
+ }
+ }
+ };
+
+ for (var i = 0; i < table.dim[margin]; i++) {
+ calcGroup(i);
+ }
+ }
+ return Object.freeze(new Table(table.dim, table.dimnames, array));
+};
+
exports.addMargins = addMargins;
+exports.prop = prop;
View
@@ -220,6 +220,44 @@ describe("xtabs", function() {
});
});
+ describe("prop", function() {
+ var data = {
+ department: xtabs.factor(["MIS", "MIS", "HR", "TR", null, "TR", "MIS"]),
+ team: xtabs.factor(["Oversea", "PO", "HR", "Tech", null, "Tech", "PO"]),
+ gender: xtabs.factor(["M", "F", "F", "M", "F", "M", "M"])
+ };
+
+ it("proportions of the whole", function() {
+ var t = xtabs.table(data, "department", "gender");
+ var t_ = xtabs.prop(t);
+ t_.array.should.eql([2/6, 1/6, 0, 1/6, 2/6, 0]);
+ });
+
+ it("proportions of the row", function() {
+ var t = xtabs.table(data, "department", "gender");
+ var t_ = xtabs.prop(t, 0);
+ t_.array.should.eql([2/3, 1/3, 0, 1, 1, 0]);
+ });
+
+ it("proportions of the column", function() {
+ var t = xtabs.table(data, "department", "gender");
+ var t_ = xtabs.prop(t, 1);
+ t_.array.should.eql([.5, .5, 0, .5, .5, 0]);
+ });
+
+ it("proportions of margin 2", function() {
+ var t = xtabs.table(data, "department", "team", "gender");
+ var t_ = xtabs.prop(t, 2);
+ t_.get("MIS").array.should.eql([1/4, 0, 1/4, 1/2, 0, 0, 0, 0]);
+ });
+
+ it("single dimension", function() {
+ var t = xtabs.table(data, "gender");
+ var t_ = xtabs.prop(t);
+ t_.array.should.eql([4/7, 3/7]);
+ });
+ });
+
describe("addMargins", function() {
var data = {
department: xtabs.factor(["MIS", "MIS", "HR", "TR", null, "TR", "MIS"]),

0 comments on commit b107406

Please sign in to comment.