Coder Social home page Coder Social logo

savvy's Introduction

savvy

Read all fields from a .sav file. All fields include the full Schema and all data cells as a Row[]

Still in development: TODO: expose objects of Column classes TODO: concatenate long string column values TODO: uncompressed data files TODO: unrecognized codes

From a node.js Buffer using fs.readFile

fs = require('fs');

let all;
const parser = new SavParser();
// with async readFile
fs.readFile('some/path/to/file.sav', (err, data) => {
    parser.all(new Feeder(data.buffer)).then(
        result => all = result
    )
});
// with syncronous `readFileSync`
parser.all(
    new Feeder(fs.readFileSync('/some/path/to/file.sav').buffer)
).then(
    parsed => all = parsed
);
// nodejs Buffers may need to be sliced when accessing the underlying ArrayBuffer
// It's always safer to slice from the byteOffset (which commonly is 0) and byteLength
new Feeder(
    buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength)
);

In the browser with File API

<input type="file" onchange = "onChange"></input>
const all;
function onChange(event){
    const file = event.target.files[0];
    const reader = new FileReader();
    const parser = new SavParser();
    reader.onload = function(data){
        data.arrayBuffer().then(
            buffer => parser.all(new Feeder(buffer))
        ).then(
            parsed => all = parsed
        );
    }
    reader.readAsArrayBuffer(file);
}

Parsing less than the complete data file

const parser = new SavParser();

// read only the meta fields from a sav file
parser.meta(new Feeder(buffer)).then(parsed => {/* do stuff */});

// read only the header fields from a sav file
// Header here refers to the head of the columns of the data, i.e.
// properties of the columns in the data file
parser.headers(new Feeder(buffer)).then(parsed => {/* do stuff */});

// read all schema fields from a sav file
// Schema here refers to all information except for the data cells themselves
parser.schema(new Feeder(buffer)).then(parsed => {/* do stuff */});

DataSet interface for parsed data Savvy class implements DataSet

const parser = new SavParser();
let dataset;
parser.all(new Feeder(buffer)).then(
    parsed => dataset = new Savvy(parsed)
)
// n : number - number of cases
dataset.n
// names : Array<string> - column names (short unique names)
dataset.names
// labels : Map<string, string> - column long labels (key-value by unique name)
dataset.labels
// row(index : number) : Map<string, number | string> - get a row as key-value map
dataset.row(0)
// col(key : string) : Array<number> | Array<string> - get a column as an array
dataset.col('IDField')
// view(indices? : Array<number>, keys? : Array<string>) : DataSet - subset by rows/columns

See types.d.ts file for how parsed data is encoded

savvy's People

Contributors

jonathankroening avatar mheripsos avatar mhermher avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

savvy's Issues

Determining which Header a Scale belongs to

Hey there,

Is there a way to determine which Header entry a Scale belongs to?

It looks like each Scale (in internals.levels) has a Set of indices that indicate which columns they belong to but I gather these indices correspond to internal columns and not the ones that appear in the list of Headers since the range of indices in my own dataset is much larger than the number of Header entries.

For example, how would I figure out that the Header for gender below corresponds to the Scale entry shown in parsed.internal.levels?

...
const parsed = {
  // ... other Parsed entries
  headers: [
   {
      name: 'Gender',
      label:  'What gender do you identify with?',
   }
   // ... other Headers 
  ],
  internal: {
  levels: [
    indices: {5},
    map: {1 => 'Male', 2 => 'Female', 3 => 'Other'},
  ],
  // ... other Internal entries
  }

Edit: It looks like I can do something like this to get the Scale entry for a column if I pass the label from the Header entry:

const dataset = new Savvy(parsed)
const column = dataset.field('Gender')
console.log(column)
/**
  _levels: {1 => 'Male', 2 => 'Female', 3 => 'Other'},
  // ... rest of column entries
*/

Put Validators on Dataset Set Methods

Need to guard against incompatible set properties for names/labels/levels/missing. Specifically in that the keys to any of these props must match the underlying data keys.

Sav Export Enquiry

Would be be open for some consultancy to extend this project? If so I would be interested in discussing it with you.

kind regards
Gary Nelson

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.