I have following data frame in R:
df <- data.frame(RowNames <- c("FirstCol","SecondCol","ThirdCol","FourthCol"),
FirstCol <- c(0.4,0.5,0.1,0.2),
SecondCol <- c(0.8,0.6,0.4,0.1),
ThirdCol <- c(0.7,0.1,0.2,0.6),
FourthCol <- c(0.5,0.3,0.1,0.9))
names(df) <- c("RowNames", "FirstCol", "SecondCol", "ThirdCol", "FourthCol")
And I like to convert this data frame into very specific json file for further heatmap drawing concept:
# desired output
{
"x": [ "FirstCol", "SecondCol", "ThirdCol", "FourthCol" ],
"y": [ "FourthCol", "ThirdCol", "SecondCol", "FirstCol" ],
"z": [
[ 0.2, 0.1, 0.6, 0.9 ],
[ 0.1, 0.4, 0.2, 0.1 ],
[ 0.5, 0.6, 0.1, 0.3 ],
[ 0.4, 0.8, 0.7, 0.5 ]]
}
Is there any specific approach, how to do that in the easiest way? I really have no idea where should I start. Thank you very much for any of your help in advance.
We can use toJSON from jsonlite by placing the names and the data (reversed from last row to first row) in a named list.
library(jsonlite)
toJSON(list(x=names(df)[-1], y=rev(names(df)[-1]),
z=`dimnames<-`(as.matrix(df[nrow(df):1,-1]), NULL)))
{
"x":["FirstCol","SecondCol","ThirdCol","FourthCol"],
"y":["FourthCol","ThirdCol","SecondCol","FirstCol"],
"z":[[0.2,0.1,0.6,0.9],
[0.1,0.4,0.2,0.1],
[0.5,0.6,0.1,0.3],
[0.4,0.8,0.7,0.5]]
}
Related
I am working with the rigged figure gltf:
Not to post the entire gltf, i will post the relevant nodes:
{
"children": [
21,
1
],
"matrix": [
1.0,
0.0,
0.0,
0.0,
0.0,
0.0,
-1.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
0.0,
0.0,
1.0
],
"name": "Z_UP"
},
{
"mesh": 0,
"skin": 0,
"name": "Proxy"
},
...
{
"translation": [
0.0,
0.06650590896606446,
0.0
],
"rotation": [
4.2157907720330458e-10,
0.9999844431877136,
-0.005583992227911949,
-7.549667913053783e-8
],
"scale": [
1.0,
1.0000001192092896,
1.0
],
"name": "neck_joint_2"
},
{
"children": [
2
],
"name": "Armature"
}
So node 0 is the parent of node 1 and node 21. However the skin in node 1 has it's joints starting at node 2. i.e. the skin in node 1 is the "parent" of the skeleton defined by the nodes from 2 to 21.
The question is then, should the transformation in node 0 be applied twice to the nodes in the skin?
From glTF Specifications — Skins...
Client implementations should apply only the transform of the skeleton root node to the skinned mesh while ignoring the transform of the skinned mesh node.
So in this sample, the inherited world transform of Node 1 is not applied to the joints/bones of the skin. In other words, the node-skin relationship does not apply any transformation to the joints of the skin.
I have two json files in the exact format as below. My goal is to combine them and keep the exact same format - just basically stack one on top of the other.
I have tried the following but this does not correctly combine both files and preserve the format as both files are bracketed with [ ] separately. How does one combine and keep only one pair of brackets around the entire file?
files <- c("test.json","test2.json")
jsonl <- lapply(files, function(f) fromJSON(file = f))
jsonc <- toJSON(jsonl)
write(jsonc, file = "two.json")
Are there any better solutions in R?
test.json:
[
{
"vendor": 0,
"startTime": 4380,
"endTime": 4445
},
{
"vendor": 0,
"startTime": 4448,
"endTime": 4453
},
{
"vendor": 0,
"startTime": 4696,
"endTime": 4880
}
]
undesired output:
[
[
{"vendor":0,"startTime":4380,"endTime":4445},
{"vendor":0,"startTime":4448,"endTime":4453},
{"vendor":0,"startTime":4696,"endTime":4880}],
[{"vendor":0,"startTime":4380,"endTime":4445},
{"vendor":0,"startTime":4448,"endTime":4453},
{"vendor":0,"startTime":4696,"endTime":4880}
]
]
desired output:
[
{"vendor":0,"startTime":4380,"endTime":4445},
{"vendor":0,"startTime":4448,"endTime":4453},
{"vendor":0,"startTime":4696,"endTime":4880},
{"vendor":0,"startTime":4380,"endTime":4445},
{"vendor":0,"startTime":4448,"endTime":4453},
{"vendor":0,"startTime":4696,"endTime":4880}
]
You can join them before writing using rbind
files <- c("test.json","test2.json")
jsonl <- do.call("rbind", lapply(files, function(f) fromJSON(f)))
write(toJSON(jsonl), file = "two.json")
I have a data that shows a series of actions (column Actions ) performed by several users (column Id). The order of the data frame is important - it is the order the actions were performed in. For each id, the first action performed is start. Consecutive identical actions are possible (for example, the sequence start -> D -> D -> D is valid ). This is some code to generate data:
set.seed(10)
i <- 0
all_id <- NULL
all_vals <- NULL
while (i < 5) {
i <- i + 1
print(i)
size <- sample(3:5, size = 1)
tmp_id <- rep(i, times = size + 1)
tmp_vals <- c("start",sample(LETTERS, size = size) )
all_id <- c(all_id, tmp_id)
all_vals <- c(all_vals, tmp_vals)
}
df <- data.frame(Id = all_id,
Action = all_vals)
Goal - transform this data in a JSON nested on multiple levels that will be used in a D3.js visualization (like this). I would like to see a counter for how many times each child appears for their respective parent (an maybe even a percentage out of the total appearances of the parent) - but I hope I can do that myself.
Expected output below - this is generic, not from the data I generated above, and real data will have quite a lot of nested values ( count and percentage are optional at this point in time):
{
"action": "start",
"parent": "null",
"count": "10",
"percentage": "100",
"children": [
{
"action": "H",
"parent": "start",
"count": "6",
"percentage": "60",
"children": [
{
"action": "D",
"parent": "H",
"count": "5",
"percentage": "83.3"
},
{
"action": "B",
"parent": "H",
"count": "3",
"percentage": "50"
}
]
},
{
"action": "R",
"parent": "start",
"count": "4",
"percentage": "40"
}
]
}
I know I am supposed to post something I've tried, but I really don't have anything remotely worth of being shown.
I have just started writing some R -> d3.js converters in https://github.com/timelyportfolio/d3r that should work well in these type situations. I will work up an example later today with your data.
The internal hierarchy builder in https://github.com/timelyportfolio/sunburstR also might work well here.
I'll add to the answer as I explore both of these paths.
example 1
set.seed(10)
i <- 0
all_id <- NULL
all_vals <- NULL
while (i < 5) {
i <- i + 1
print(i)
size <- sample(3:5, size = 1)
tmp_id <- rep(i, times = size + 1)
tmp_vals <- c("start",sample(LETTERS, size = size) )
all_id <- c(all_id, tmp_id)
all_vals <- c(all_vals, tmp_vals)
}
df <- data.frame(Id = all_id,
Action = all_vals)
# not sure I completely understand what this is
# supposed to become but here is a first try
# find position of start
start_pos <- which(df$Action=="start")
# get the sequences
# surely there is a better way but do this for now
sequences <- paste(
start_pos+1,
c(start_pos[-1],nrow(df))-1,
sep=":"
)
paths <- lapply(
sequences,
function(x){
data.frame(
t(as.character(df[eval(parse(text=x)),]$Action)),
stringsAsFactors=FALSE
)
}
)
paths_df <- dplyr::bind_rows(paths)
# use d3r
# devtools::install_github("timelyportfolio/d3r")
library(d3r)
d3_nest(paths_df) # if want list, then json=FALSE
# visualize with listviewer
# devtools::install_github("timelyportfolio/listviewer")
listviewer::jsonedit(d3_nest(paths_df))
i'm having trouble with a very nasty nested JSON.
The format is like this
{
"matches": [
{
"matchId": 1,
"region": "BR",
"participants": [
{
"participantId": 0,
"teamId": 200,
"stats": {
"winner": true,
"champLevel": 16,
"item0": 3128,
}
{
"matchId": 2,
"region": "BR",
"participants": [
{
"participantId": 0,
"teamId": 201,
"stats": {
"winner": false,
"champLevel": 18,
"item0": 3128,
"item1": 3157,
"item1": 3158,
}
As you can see in the second match the number of items increased, but in the data frame the first row will have the same collumns:
MatchId region ... stats.winner stats.champLevel stats.item0 stats.item1 stats.item2
1 BR TRUE 16 3128 1 BR
1 BR TRUE 16 3128 3157 3158
See the first row is smaller than the second, so R recycle the values ....
If you want the full data you can grab it at:
http://pastebin.com/HQDf2ase
How I parsed the json to data.frame:
json.matchData <- fromJSON(file="file.json"))
Unlist the elements of the Json and convert it to a data frame
matchData.i <- lapply(json.matchData$matches, function(x){ unlist(x)})
Transform into Data Frame
matchData <- do.call("rbind", matchData.i)
matchData <- as.data.frame(matchData)
But the dataframe is messed up, because some fields should be NA but they are filled with wrong values.
I think using the plyr rbind.fill() function would be helpful here. How about this
library(plyr)
matchData <- rbind.fill(lapply(matchData.i,
function(x) do.call("data.frame", as.list(x))
))
the lapply() bit is to turn the intermediate lists into data.frames which rbind.fill requires.
I've been working with a 2 column system so far but feel I'm needing a third and that 3 spread across the screen doesn't give much of a view without adjusting the width every time.
It's there a way to get the grid layout but have the bottom half of the screen one file.
I know it's a long shot but wondering if anyone knows of anything
Found that you can edit for custom layouts in Packages/default/Main.sublime-menu
Having problems saving though error in trying to parse file: expected value in ~/library/application support/sublime text 2/packages/default/Main.sublime-menu:407:21
Edited: for better layout
Found something that is similar, been trying to mod it but don't understand how the cells work
This one is similar
"args":
{
"cols": [0.0, 0.5, 1.0],
"rows": [0.0, 0.5, 1.0],
"cells": [
[0, 0, 1, 2], // (0.0, 0.0) -> (0.5, 1.0)
[1, 0, 2, 1], // (0.5, 0.0) -> (1.0, 0.5)
[1, 1, 2, 2] // (0.5, 0.5) -> (1.0, 1.0)
]
}
which gives
Assuming these are just coordinates with 0,0 at the upper left, something like this should work:
[0, 0, 1, 1],
[1, 0, 2, 1],
[0, 1, 2, 2]
Edit: Just tested, and it does.
Create the file Main.sublime-menu in your Packages > User folder (best to leave the default menu alone) and put the following code in it:
[{
"id": "view",
"children": [{
"id": "layout",
"children": [{
"command": "set_layout",
"caption" : "Custom: 3 Pane",
"mnemonic": "C",
"args": {
"cols": [0.0, 0.5, 1.0],
"rows": [0.0, 0.5, 1.0],
"cells": [
[0, 0, 1, 1],
[1, 0, 2, 1],
[0, 1, 2, 2]
]
}
}]
}]
}]
You will see Custom: 3 Pane in your layout options. No need to restart Sublime Text.
For anyone interested, here is a gist containing this layout as well as a flipped version.
This was very helpful for visualizing what points the coordinates are referring to: http://www.sublimetext.com/forum/viewtopic.php?f=6&t=7284&start=0&hilit=set+layout