我正在使用D3和JavaScript来处理某些csv数据。这个想法是要记录人们一整天的去向:他们可能开始在家,去杂货店,上学,工作等等。每次有人离开他们的住所,都会在csv文件中记录一个新行。因此,当Sally醒来时,它会记录Sally,home
,当她离开学校时,它会记录Sally,school
,依此类推。这些位置是任意的,可以按任意顺序排列,并且可能还有更多的位置。
我的csv文件如下所示:
name,place
Sally,home
Joe,home
Bill,work
Joe,work
Sally,school
Sally,grocery
Bill,salon
Joe,grocery
我想在同一人的下一步中向每一行添加一列。本质上,我希望数据能够反映
home
和school
之间,school
和grocery
之间或相邻步骤之间的转换。在第一个数据点中,Sally在家里,而下次提到她时,她在学校。因此,我希望第一个数据点(而不只是Sally, home
)更改为Sally, home, school
以反映过渡。因此,以上内容经过操作后应如下所示:name,place,next
Sally,home,school
Joe,home,work
Bill,work,salon
Joe,work,grocery
Sally,school,grocery
Sally,grocery
Bill,salon
Joe,grocery
然后,我要删除每个人的最后一步:基本上,没有“下一个”列的所有内容(这些内容可能并不总是最后三行)。最终结果如下所示:
name,place,next
Sally,home,school
Joe,home,work
Bill,work,salon
Joe,work,grocery
Sally,school,grocery
我唯一的想法是使用嵌套的for循环来查找下一个匹配的名称,然后以某种方式添加新列...这是我的尝试,但是您不能只这样声明一个新列。
d3.csv("data.csv", function(error, data) {
for(i=0; i<data.length; i++){
for(j=0; j<data.length; j++){
if (data[i].name === data[j].name){
data[i].next = data[j].place;
break;
}
}
}
});
朝正确方向的任何指针将不胜感激(最终目标是能够将此流程放入D3的Sankey图中,如果有帮助的话)。
最佳答案
您的意思是“但不能像这样声明一个新列”?是的,您可以(当然,我要使用的是数据数组,而不是实际的CSV。但是,如果您确实要保存新的CSV文件,请相应地编辑问题)并删除D3标签,因为D3没有此方法)。
我要在您的代码中做的唯一更改是在外部(j
)循环之后的一个位置开始内部(i
)循环:
for (i = 0; i < data.length; i++) {
for (j = i + 1; j < data.length; j++) {
if (data[i].name === data[j].name) {
data[i].next = data[j].place;
break;
}
}
}
然后,我们删除没有
next
属性的对象:var finalData = data.filter(function(d) {
return d.next
});
这是带有您的数据的演示:
var data = d3.csvParse(d3.select("#csv").text());
for (i = 0; i < data.length; i++) {
for (j = i + 1; j < data.length; j++) {
if (data[i].name === data[j].name) {
data[i].next = data[j].place;
break;
}
}
}
var finalData = data.filter(function(d) {
return d.next
});
console.log(finalData)
pre {
display: none;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<pre id="csv">name,place
Sally,home
Joe,home
Bill,work
Joe,work
Sally,school
Sally,grocery
Bill,salon
Joe,grocery</pre>