Load CSV from R matrix into D3.js - d3.js

I have a 2 column matrix I've saved out of R that looks like :
,y
4.93707840,-2.17356434
4.41122212,-1.96256698
4.21076739,-1.75156962
4.06441510,-1.54057226
The code I'm using is :
var data = d3.text("2013.csv", function(unparsedData)
{
var dataset = d3.csv.parseRows(unparsedData);
// Code here
})
Only the second column is imported. There is a header row which contains ,y which I really need to skip or replace.
Any ideas?
I tried this :
var dataset
d3.csv("2013.csv", function (error, dataset) {
console.log(dataset)
But still only the 2nd column is imported.

Related

How to store data for use in multiple data validation using GAS?

I have a script running on Google Sheets, which brings data from another spreadsheet/file as an array and sets one of its column's data as a data validation into a cell. Then, as the user picks one option of this data validation, the script goes back to that file and brings its related data and sets it in an adjacent column and this repeats about 3 times, making the process slow.
I was wondering if that would be possible to store the first data collection into the document property and set the data validations by grabbing related information from that data set, instead of going to the other file everytime.
Here's an update, with a working version:
function listaCategorias() {
let listaGeral = sheetBDCadProd.getRange(2, 1, sheetBDCadProd.getLastRow(), 45).getValues();//Gets all values
//Extracts a column of interest for this first data validation setting
let categorias = [];
for (let a = 0; a < listaGeral.length; a++) {
categorias.push(listaGeral[a][17])
}
let uniqueCat = [...new Set(categorias)]; //Gets a list of unique values. Not sure how I'd do that within new Set, so I did a for loop before
//Sets the data validation
const cell = sheetVendSobEnc.getRange('B5');
const validationCat = SpreadsheetApp.newDataValidation().requireValueInList(uniqueCat).setAllowInvalid(false).build();
cell.clearContent();
cell.clearDataValidations();
cell.setDataValidation(validationCat);
//Saves the data into the document property for usage in the next script/data validation
listaGeral = JSON.stringify(listaGeral)
PropertiesService.getDocumentProperties().setProperty('listaGeral', listaGeral);
}
//This is getting one of the columns, based on the option picked..the one generated by the data validation above.
function listaDescricao() {
const categoria = sheetVendSobEnc.getRange('B5').getValue();
const dadosCadProd = PropertiesService.getDocumentProperties().getProperty('listaGeral')
let cadGeral = JSON.parse(dadosCadProd);
//Filters the elements matching the option picked
let filteredNomeSobEnc = cadGeral.filter(function (o) { return o[17] === categoria });
//Filters unique values
let listToApply = filteredNomeSobEnc.map(function (o) { return o[7] }).sort().reverse();
let descUnica = listToApply.filter((v, i, a) => a.indexOf(v) === i);
Logger.log('Descrição Única: ' + descUnica)
}
It's working, but I'd like to know the rooms for improvement here.
Thanks.

For loop to check values from two spreadsheets

I have two spreadsheets:
Column A on sheet 6th&7thRoster lists all IDs in a sample, contains 853 items.
Column C on sheet alreadySubmitted contains the IDs of users who've completed a task. Contains 632 items.
I'm trying to parse through both columns. If a user from Column A of sheet 6th&7thRoster matches a user from Column C of sheet sandboxAlreadySubmitted, I want to write the word "Yes" on Column I of the current row of sheet 6th&7thRoster. When using the code below, I'm not seeing not seeing any instances of the word "Yes" on Column I of 6th&7thRoster, even though I know there's multiple places where that should be the case.
function checkRoster() {
var mainSheet = SpreadsheetApp.openById('XXXXXXX');
var roster = mainSheet.getSheetByName('6th&7thRoster');
var submissions = mainSheet.getSheetByName('alreadySubmitted');
var rosterLastRow = roster.getLastRow();
var submissionsLastRow = submissions.getLastRow();
var rosterArray = roster.getRange('A2:A853').getValues();
var submissionsArray = submissions.getRange('C2:C632').getValues;
var i;
var x;
for (i = 1; i < 853; i++) {
for (x = 1; x < 632; x++){
if (rosterArray[i] == submissionsArray[x]){
roster.getRange(i, 9).setValue("Yes");
}
}
}
}
Feedback on how to solve and achieve this task will be much appreciated. For confidentiality, I cannot share the original sheets.
You want to compate the values of A2:A853 of 6th&7thRoster and C2:C632 of alreadySubmitted.
When the values of C2:C632 of alreadySubmitted are the same with the values of A2:A853 of 6th&7thRoster, you want to put Yes to the column "I".
If my understanding is correct, how about this modification? Please think of this as just one of several possible answers.
Modified script:
function checkRoster() {
var mainSheet = SpreadsheetApp.openById('XXXXXXX');
var roster = mainSheet.getSheetByName('6th&7thRoster');
var submissions = mainSheet.getSheetByName('alreadySubmitted');
var rosterLastRow = roster.getLastRow();
var submissionsLastRow = submissions.getLastRow();
var rosterArray = roster.getRange('A2:A853').getValues();
var submissionsArray = submissions.getRange('C2:C632').getValues(); // Modified
// I modified below script.
var obj = submissionsArray.reduce(function(o, [v]) {
if (v) o[v] = true;
return o;
}, {});
var values = rosterArray.map(function([v]) {return [obj[v] ? "Yes" : ""]});
roster.getRange(2, 9, values.length, values[0].length).setValues(values);
}
Flow:
Retrieve values from A2:A853 of 6th&7thRoster and C2:C632 of alreadySubmitted.
Create an object for searching the values from the values of alreadySubmitted.
Create the row values for putting to 6th&7thRoster.
References:
reduce()
map()
If I misunderstood your question and this was not the direction you want, I apologize.

DC.js, crossfilter - generic grouping with varying number of columns

I'm trying to create a generic composite chart that would take any csv file, read the columns and create a composite line chart with one line per column.
In this use case, the first column is always TimeStamp in all csv's and this will not be changed, while the rest of the columns may vary.
To get the column names from any csv, I am using the following line of code.
var mappedArray = d3.entries(data[0]);
Say, my mappedArray is like this :
["Date", "c1", "c2", "c3"]
I have created the Dimension for timestamp as follows:
var DateDim = ndx.dimension(function(d){return timeFmt(d[mappedArray[0].key]); });
For a single valued group, i would use something like this:
var testGrp = DateDim.group().reduceSum(function(d){return +d[mappedArray[1].key]; });
For a multi valued group, I tried something like this:
var testGrp1 = testDim.group().reduce(
function(p,v){
++p.count;
p.col1 = +v[mappedArray[1].key];
p.col2 = +v[mappedArray[2].key];
...
p.coln = +v[mappedArray[n].key];
return p;
},...
But, I cannot hard code like this, as the 'n' in mappedArray[n] may keep changing.
How can I recreate this group by using mappedArray.length?
You recreate by using the index field operator []. Use a for loop to create as many p.colX fields as needed.
var testGrp1 = testDim.group().reduce(
function(p,v){
++p.count;
for (let i = 1; i < mappedArray.length; i++) {
p["col" + i] = +v[mappedArray[i].key];
}
return p;
},...
Edit
The answer to your question in the comment about the chart.compose.
A possible way of doing is to create a function that constructs the array needed.
function makeComposeArray() {
var composeArr = [];
for(let i=1; i<=mappedArray.length; i++) {
composeArr.push(
dc.lineChart(chart)
.group(testGrp1, function(d){return d['col'+i]})
.valueAccessor(function(d){return d.value["col" + i]})
);
}
return composeArr;
}
chart.compose(makeComposeArray());

Mismatched range sizes in FILTER()

I have a pivot table of info, with totals (the totals columns contain the word "Total"), that I would like to process further. I created a new sheet and use
=ARRAYFORMULA('Pivot Table mins'!A:B)
to grab the first two columns.
But then I want to "import" over JUST the columns that have the word "Total" in them, so I created:
=FILTER('Sheet'!A:X,MMULT(REGEXMATCH('Sheet'!A:X,"Total"),ROW(INDIRECT("a1:a"&COLUMNS('Sheet'!A:X)))^0))
e.g. if the Pivot Table data spans columns A to Z, but only columns D & F have the keyword "Total", I only want to "import" those columns.
However I am getting an error message:
FILTER has mismatched range sizes. Expected row count: 1250. column count: 1. Actual row count: 1, column count: 1.
I've read that it could be that the ranges do not match, however I have all ranges matching.
Side note: There are 1242 rows in both sheets.
function onOpen() {
SpreadsheetApp.getActiveSpreadsheet().addMenu(
'Copy Data', [
{ name: 'Copy', functionName: 'copyTotalColumns' },
]);
}
function copyTotalColumns() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var s=ss.getSheetByName("Sheet")
var s1=ss.getSheetByName("Sheet2")
var lastColumn = s.getLastColumn();
var lastRow= s.getLastRow()
var startCol=3 //column to start total rows
var data = s.getRange(1,1,1,lastColumn).getValues();//get headers
for(var i=0;i<data[0].length;i++){
if( data[0][i]=="Total"){
var copyFrom=s.getRange(2, i+1, lastRow,1).getValues()//get total column
var copyTo=s1.getRange(2, startCol,
lastRow,1).setValues(copyFrom)//set total column on new sheet
startCol=startCol+1 //index column
}
}}

crossfilter: obtain the count of values falling into the product of two columns

I have a data set like
{"parent":"/home","inside":"/files","filename":"type.jar",
"extension":"jar","type":"modified","archive"}
Likewise many there are many rows in the json array. I am using crossfilter to read the data and plot graphs and datatables. the Type in the data set has values "added", "modified" and "deleted".
I want to create a data table like
Extension | Added | Modified | Deleted
where added, modified and deleted will hold the count of the files with the specific extension. Can anyone suggest me a way to do so?
So far I have created a dimension like this:
var extensionType = facts.dimension(function(d) {
return d.extension; });
var extensionTypeGroup=extensionType.group();
and I get a grouped output like this,
{"key":"class","value":424},
{"key":"js","value":176},
{"key":"properties","value":26},
{"key":"jar","value":10},
{"key":"css","value":8},
{"key":"txt","value":6},
{"key":"war","value":4},
{"key":"png","value":4},
{"key":"handlebars","value":4},
{"key":"jar_local","value":2},
{"key":"aar","value":2}
How do I get the separate count of added deleted and modified?
Probably the easiest way to do this is to reduce to an object rather than a single value.
This is covered in the FAQ: How do I reduce multiple values at once? What if rows contain a single value but a different value per row? You probably just needed the right search terms to find it.
Actually it looks like the code from the FAQ will work for you unmodified:
var extensionTypeGroup = extensionType.group().reduce(
function(p, v) { // add
p[v.type] = (p[v.type] || 0) + v.value;
return p;
},
function(p, v) { // remove
p[v.type] -= v.value;
return p;
},
function() { // initial
return {};
});

Resources