Book Image

Building Data-Driven Applications with Danfo.js

By : Rising Odegua, Stephen Oni
Book Image

Building Data-Driven Applications with Danfo.js

By: Rising Odegua, Stephen Oni

Overview of this book

Most data analysts use Python and pandas for data processing for the convenience and performance these libraries provide. However, JavaScript developers have always wanted to use machine learning in the browser as well. This book focuses on how Danfo.js brings data processing, analysis, and ML tools to JavaScript developers and how to make the most of this library to build data-driven applications. Starting with an overview of modern JavaScript, you’ll cover data analysis and transformation with Danfo.js and Dnotebook. The book then shows you how to load different datasets, combine and analyze them by performing operations such as handling missing values and string manipulations. You’ll also get to grips with data plotting, visualization, aggregation, and group operations by combining Danfo.js with Plotly. As you advance, you’ll create a no-code data analysis and handling system and create-react-app, react-table, react-chart, Draggable.js, and tailwindcss, and understand how to use TensorFlow.js and Danfo.js to build a recommendation system. Finally, you’ll build a Twitter analytics dashboard powered by Danfo.js, Next.js, node-nlp, and Twit.js. By the end of this app development book, you’ll be able to build and embed data analytics, visualization, and ML capabilities into any JavaScript app in server-side Node.js or the browser.
Table of Contents (18 chapters)
1
Section 1: The Basics
3
Section 2: Data Analysis and Manipulation with Danfo.js and Dnotebook
10
Section 3: Building Data-Driven Applications

Understanding Array and Object methods

Arrays and Objects are the two most important data types in JavaScript. As such, we have dedicated a section to talking about some of their methods. We will start with the Array methods.

Array methods

We can't discuss how to build a data-driven product without discussing Array methods. Knowing different Array methods gives us the privilege of accessing our data and creating tools to manipulate/handle our data.

An array can be created in two different forms:

let data = []
// or
let data = new Array()

The [ ] method is mostly used for initializing arrays, while the new Array() method is used mostly to create an empty array of an n size, as shown in the following code snippet:

let data = new Array(5)
console.log(data.length) // 5 
console.log(data) //  [empty × 5]

The empty array created can later be filled with values as shown in the following code:

data[0] = "20"
data[1] = "John"
data[2] = "Doe"
data[3] = "1948"
console.log(data) // ["20", "John","Doe","1948", empty] 
// try access index 4  
console.log(data[4]) //  undefined

Creating such an empty array is not limited to using the new Array() method. It can also be created with the [ ] method, as shown in the following code snippet:

let data = [] 
data.length = 5; // create an empty array of size 5
console.log(data)  // [empty × 5]

You can see that we explicitly set the length after creation, and as such, the new Array() method is more convenient.

Let's now look at some of the common array methods that will be used in building some of our data-driven tools.

Array.splice

Deleting and updating array values will always be one of the essential things in a data-driven product. JavaScript has a delete keyword to delete a value at a particular index in an array. This method does not actually delete the value, but replaces it with an empty or undefined value, as shown in the following code:

let data = [1,2,3,4,5,6];
delete data[4];
console.log(data) // [1,2,3,4 empty, 6]

In the data variable, if we try to access the value at index 4, we will see that it returns undefined:

console.log(data[4]) // undefined

But whenever we use splice to delete a value in an array, the index of the array is re-arranged, as demonstrated in the following code snippet:

let data = [1,2,3,4,5,6]
data.splice(4,1) // delete index 4
console.log(data) // [1,2,3,4,6]

Array.splice takes in the following argument, start,[deleteCount, value-1,......N-values]. In the preceding code snippet, since we are only deleting, we make use of start and deleteCount.

The data.splice(4,1) command deletes the value starting at index 4, with only one count, hence it deletes the value at index 5.

If we replace the value 1 in data.splice(4,1) with 2, resulting in data.splice(4,2), two values (5 and 6) from the data array will be deleted, starting from index 4, as shown in the following code block:

let data = [1,2,3,4,5,6]
data.splice(4,0,10,20) // add values between 5 and 6
console.log(data) // [1,2,3,4,5,10,20,6]

data.splice(4,0,10, 20); specifies starting at index 4, and 0 specifies that no values should be deleted, while adding the new values (10 and 20) between 5 and 6.

Array.includes

This method is used for checking whether an array contains a particular value. We show an example in the following code snippet:

let data = [1,2,3,4,5,6]
data.includes(6) // true

Array.slice

Array.slice is used to obtain an array element by specifying the range; Array.slice(start-index, end-index). Let's see an example of using this method in the following code:

let data = [1,2,3,4,5,6]
data.slice(2,4) 
//output [3,4]

The preceding code extracts elements, starting from index 2 (having element 3) to index 5. Note that the array did not output [3,4,5], but [3,4]. Array.splice always excludes the end index value, and so it uses a close end range.

Array.map

The Array.map method iterates through all the elements of an array, applies some operations to each iteration, and then returns the result as an array. The following code snippet is an example:

let data = [1,2,3,4,5,6]
let data2 = data.map((value, index)=>{
return value + index;
});
console.log(data2) // [1,3,5,7,9,11]

The data2 variable is created by iterating over each data element by using a map method. In the map method, we are adding each element (value) of the array to its index.

Array.filter

The Array.filter method is used to filter out some elements in an array. Let's see this in action:

let data = [1,2,3,4,5,6]
let data2 = data.filter((elem, index)=>{
return (index %2 == 0)
})
console.log(data2) // [1,3,5]

In the preceding code snippet, the array element of data at every even index is filtered out using the modulus (%) of 2.

There are lots of Array methods, but we covered these few methods because they are always handy during data handling, and we will not be able to cover all of them.

However, if any new method is used in later chapters of this book, we will certainly provide an explanation. In the next section, we'll discuss Object methods.

Objects

Objects are the most powerful and important data type in JavaScript, and in this section, we'll introduce some important properties and methods of objects that make working with them easier.

Accessing object elements

Accessing keys/values in an object is important, so there exists a special for...in loop for doing that:

for (key in object) {
  // run some action with keys
}

The for...in loop returns all the keys in an object, and this can be used to access Object values, as demonstrated in the following code:

let user_profile = { 
  name: 'Mary', 
  sex: 'Female', 
  age: 25, 
  img_link: 'https://some-image-link.png', 
}
for (key in user_profile) {
    console.log(key, user_profile[key]);
}
//output:
// name Mary
// sex Female
// age 25
// img_link https://some-image-link.png

In the next section, we will show how to test the existence of properties.

Testing for the existence of property

To check whether a property exists, you can use the "key" in object syntax, as demonstrated in the following code snippet:

let user_profile = { 
  name: 'Mary', 
  sex: 'Female', 
  age: 25, 
  img_link: 'https://some-image-link.png', 
}
console.log("age" in user_profile)
//outputs: true 
 
if ("rank" in user_profile) {
    console.log("Your rank is", user_profile.rank)
} else {
    console.log("rank is not a key")
}
//outputs: rank is not a key

Deleting properties

The delete keyword used before an object property will remove a specified property from an object. Look at the following example:

let user_profile = {
    name: 'Mary',
    sex: 'Female',
    age: 25,
    img_link: 'https://some-image-link.png',
}
delete user_profile.age
console.log(user_profile)
//output:
// {
//     img_link: "https://some-image-link.png",
//     name: "Mary",
//     sex: "Female"
// }

You can see that the age property has been successfully removed from the user_profile object. Next, let's look at how to copy and clone objects.

Copying and cloning objects

Assigning an old object to a new one simply creates a reference to the old object. That is, any modification made to the new object also affects the old one. For instance, in the following example, we assign the user_profile object to a new variable, new_user_profile, and then proceed to delete the age property:

let user_profile = {
    name: 'Mary',
    sex: 'Female',
    age: 25,
    img_link: 'https://some-image-link.png',
}
let new_user_profile = user_profile
delete new_user_profile.age
 
console.log("new_user_profile", new_user_profile)
console.log("user_profile", user_profile)
//output:
// "new_user_profile" Object {
//     img_link: "https://some-image-link.png",
//     name: "Mary",
//     sex: "Female"
// }
 
// "user_profile" Object {
//     img_link: "https://some-image-link.png",
//     name: "Mary",
//     sex: "Female"
// }

You will notice that deleting the age property from the user_profile object also deletes it from new_user_profile. This is because the copy is simply a reference to the old object.

In order to copy/clone objects as new and independent ones, you can use the Object.assign method, as shown in the following code:

let new_user_profile = {}
Object.assign(new_user_profile, user_profile)
 
delete new_user_profile.age
 
console.log("new_user_profile", new_user_profile)
console.log("user_profile", user_profile)
 
//output
"new_user_profile" Object {
  img_link: "https://some-image-lik.png",
  name: "Mary",
  sex: "Female"
}
"user_profile" Object {
  age: 25,
  img_link: "https://some-image-lik.png",
  name: "Mary",
  sex: "Female"
}

The Object.assign method can also be used to copy properties from more than one object at the same time. We present an example in the following code snippet:

let user_profile = {
  name: 'Mary',
  sex: 'Female',
  age: 25,
  img_link: 'https://some-image-lik.png',
}
let education = { graduated: true, degree: 'BSc' }
let permissions = { isAdmin: true }
 
Object.assign(user_profile, education, permissions);
console.log(user_profile)
//output:
// {
//     name: 'Mary',
//     sex: 'Female',
//     img_link: 'https://some-image-link.png',
//     graduated: true,
//     degree: 'BSc',
//     isAdmin: true
//   }

You can see that we were able to copy properties from two objects (education and permissions) into our original object, user_profile. In this way, we can copy any number of objects into another one by simply listing all the objects when you call the Object.assign method.

Tip

You can also perform a deep copy with a spread operator. This is actually quicker and easier to write, as demonstrated in the following example:

let user_profile = {

name: 'Mary',

sex: 'Female'

}

let education = { graduated: true, degree: 'BSc' }

let permissions = { isAdmin: true }

const allObjects = {...user_profile, ...education, ...permissions}

Spreading each object, as shown in the preceding code snippet, performs a deep copy of all properties in allObjects. This syntax is easier and quicker than the object.assign method and is largely used today.

In the next section, we will talk about another important concept relating to JavaScript objects called the this property.