Error using heatmap.2 function - heatmap

I have a 47 X 49 dataframe which I converted to a matrix
dat=as.matrix(df)
But when I use
heatmap.2(dat)
its says
`x' must be a numeric matrix.
I checked for NA values using is.na(dat) and its all FALSE.
Does anyone know this error?
Thanks!

One possible problem could be that the values in the dataframe where converted into strings instead of integers or floats, e.g.,
e.g.,
> df
n s
1 2 aa
2 3 bb
3 5 cc
> as.matrix(df)
n s
[1,] "2" "aa"
[2,] "3" "bb"
[3,] "5" "cc"
So, what you could do is to remove all letter-containing columns from the matrix and use the apply function, e.g.,
> m = matrix(rep("3", 30), 5,6)
> m
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] "3" "3" "3" "3" "3" "3"
[2,] "3" "3" "3" "3" "3" "3"
[3,] "3" "3" "3" "3" "3" "3"
[4,] "3" "3" "3" "3" "3" "3"
[5,] "3" "3" "3" "3" "3" "3"
> apply(m, 1,as.numeric)
[,1] [,2] [,3] [,4] [,5]
[1,] 3 3 3 3 3
[2,] 3 3 3 3 3
[3,] 3 3 3 3 3
[4,] 3 3 3 3 3
[5,] 3 3 3 3 3
[6,] 3 3 3 3 3

Related

How to extract values from JSON blob into new columns in R data frame?

I am stuck on the following problem:
I have a data frame that has a variable that contains JSON objects (in var2):
var1 var2
1 1 {"property1": "val1", "property2": 5}
2 2 {"property1": "val2", "property2": 8}
3 3 {"property1": "val3", "property2": 7}
4 4 {"property1": "val4", "property2": 0}
5 5 {"property1": "val5", "property3": 9}
(Code on pastebin here)
I want to extract the JSON properties in var2 and andd them to the data frame in new columns like so:
var1 var2 prop1 prop2 prop3
1 1 {"property1": "val1", "property2": 5} val1 5 NA
2 2 {"property1": "val2", "property2": 8} val2 8 NA
3 3 {"property1": "val3", "property2": 7} val3 7 NA
4 4 {"property1": "val4", "property2": 0} val4 0 NA
5 5 {"property1": "val5", "property2": 9} val5 NA 9
Given identical properties in identical sequence, I have found this way to make it work:
jsonProps <- sapply(df$var2, function(x) fromJSON(x)) %>%
t() %>%
as.data.frame()
rownames(jsonProps) <- NULL
y <- cbind(df, jsonProps)
(I am happy to receive any suggestions on how to make this more efficient, if there might be any.)
This does not work anymore when
the number of properties differs across records and/or
the sequence changes and/or
different properties are stored between records.
I am at a loss on how to dynmically create columns from the properties I find and transfer the property values correctly and would thus welcome your suggestions on how to tackle this.
You can do:
library(plyr)
library(jsonlite)
ll = lapply(df$var2, function(x) jsonlite::fromJSON(as.character(x)))
cbind(df, ldply(ll, data.frame))
# var1 var2 property1 property3 property2
#1 a {"property1": "val1", "property3": 8} val1 8 NA
#2 a {"property1": "val1", "property2": 5} val1 NA 5
Data:
df = structure(list(var11 = structure(c(1L, 1L), .Label = "a", class = "factor"),
var2 = structure(1:2, .Label = c("{\"property1\": \"val1\", \"property3\": 8}",
"{\"property1\": \"val1\", \"property2\": 5}"), class = "factor")), .Names = c("var1",
"var2"), class = "data.frame", row.names = 1:2)
This doesn't do everything you want, but perhaps is better
library("dplyr")
library("jsonlite")
get_it <- function(x) {
jsonlite::fromJSON(as.character(x))
}
tbl_df(test) %>%
rowwise() %>%
mutate(one = get_it(var2)[[1]],
two = get_it(var2)[[2]])
Source: local data frame [5 x 4]
Groups: <by row>
var1 var2 one two
(dbl) (fctr) (chr) (int)
1 1 {"property1": "val1", "property2": 5} val1 5
2 2 {"property1": "val2", "property2": 8} val2 8
3 3 {"property1": "val3", "property2": 7} val3 7
4 4 {"property1": "val4", "property2": 0} val4 0
5 5 {"property1": "val5", "property3": 9} val5 9

Adding a list of data frames to one of the variables in a data frame (R)

I am trying to create the data structure shown here (read in from RJSONIO). I need to produce this structure in R from raw data. As you can see it is a data frame of 4 variables, where the 4th variable (children) is a list of data frames. I am having trouble finding a way to create a data frame that contains a list as one of its variables.
Data Structure as read in from RJSONIO (rjsonio_frame)
'data.frame': 5 obs. of 4 variables:
$ name : chr "" "" "" "" ...
$ imageURL: chr "images/failure.png" "images/failure.png" "images/failure.png" "images/failure.png" ...
$ id : chr "2" "11" "20" "29" ...
$ children:List of 5
..$ :'data.frame': 8 obs. of 3 variables:
.. ..$ name : chr "word 1" "word 2" "word 3" "word 4" ...
.. ..$ imageURL: chr "" "" "" "" ...
.. ..$ id : chr "3" "4" "5" "6" ...
..$ :'data.frame': 8 obs. of 3 variables:
.. ..$ name : chr "word 1" "word 2" "word 3" "word 4" ...
.. ..$ imageURL: chr "" "" "" "" ...
.. ..$ id : chr "12" "13" "14" "15" ...
..$ :'data.frame': 8 obs. of 3 variables:
.. ..$ name : chr "word 1" "word 2" "word 3" "word 4" ...
.. ..$ imageURL: chr "" "" "" "" ...
.. ..$ id : chr "21" "22" "23" "24" ...
..$ :'data.frame': 8 obs. of 3 variables:
.. ..$ name : chr "word 1" "word 2" "word 3" "word 4" ...
.. ..$ imageURL: chr "" "" "" "" ...
.. ..$ id : chr "30" "31" "32" "33" ...
..$ :'data.frame': 8 obs. of 3 variables:
.. ..$ name : chr "word 1" "word 2" "word 3" "word 4" ...
.. ..$ imageURL: chr "" "" "" "" ...
.. ..$ id : chr "39" "40" "41" "42" ...
I can create a list of data frames easily (the imageURL is blank):
list_of_frames
[[1]]
name imageURL id
1 word1 3
2 word2 4
3 word3 5
4 word4 6
5 word5 7
[[2]]
name imageURL id
1 word1 8
2 word2 9
3 word3 10
4 word4 11
5 word5 12
[[3]]
name imageURL id
1 word1 13
2 word2 14
3 word3 15
4 word4 16
5 word5 17
But how can I add this list to the character variable of the top most data frame (assume I can already make the rest of the required data frame)? I have tried this:
final_frame <- data.frame(name=name_vector, imageURL=image_vector, id=id_vector, children=list_of_frames)
The name, imageURL, and id all go into the data frame correctly, but the list_of_frames does not. If I will subset the CORRECT version from RSJONIO here (names are blank):
rjsonio_frame[[4]]
name imageURL id
1 images/failure.png 2
2 images/failure.png 11
3 images/failure.png 20
4 images/failure.png 29
5 images/failure.png 38
children
1 word 1, word 2, word 3, word 4, word 5, word 6, word 7, word 8, , , , , , , , , 3, 4, 5, 6, 7, 8, 9, 10
2 word 1, word 2, word 3, word 4, word 5, word 6, word 7, word 8, , , , , , , , , 12, 13, 14, 15, 16, 17, 18, 19
3 word 1, word 2, word 3, word 4, word 5, word 6, word 7, word 8, , , , , , , , , 21, 22, 23, 24, 25, 26, 27, 28
Not the appearance of the children variable. I subset this further I get:
rjsonio_frame[[4]][[4]]
[[1]]
name imageURL id
1 word 1 3
2 word 2 4
3 word 3 5
4 word 4 6
5 word 5 7
6 word 6 8
7 word 7 9
8 word 8 10
[[2]]
name imageURL id
1 word 1 12
2 word 2 13
3 word 3 14
4 word 4 15
5 word 5 16
6 word 6 17
7 word 7 18
8 word 8 19
[[3]]
name imageURL id
1 word 1 21
2 word 2 22
3 word 3 23
4 word 4 24
5 word 5 25
6 word 6 26
7 word 7 27
8 word 8 28
This looks like my list_of_frames. But my final_frame does not show this.
Just put it outside the data.frame initialization, so data.frame() will not unlist the children:
final_frame <- data.frame(
name=name_vector,
imageURL=image_vector,
id=id_vector)
final_frame$children <- list_of_frames
EDIT (for sake of completeness):
... or as akrun suggested - you can inhibit conversion by
final_frame <- data.frame(
name=name_vector,
imageURL=image_vector,
id=id_vector,
children = I(list_of_frames))

MySql combining update with an inner join and limit

I'm trying to update a row in table amga with just one row from table amgb joined by their itemTempId.
My problem is that, there may be upto 6 rows in table amgb for that itemTempIdand I need to use only one from it for the update.
I'm familiar with doing updates with joins, but when I added a Limit (so as to get just one row) I get the error message Incorrect usage of update and limit. I read that this is not possible, but would there be another way to do this?
amga
"id" "itemId" "itemTempId" "itemImageName" "itemName" "itemCountry" "userId"
"1" "US1" "T001" \N "Samsung Galaxy Note 5" "US" "1"
"2" "CA2" "T002" \N "Samsung Galaxy Note 6" "CA" "2"
"3" "UK3" "T003" \N "Samsung Galaxy Note 7" "UK" "3"
amgb
"id" "itemId" "itemTempId" "itemImageName" "userId"
"1" "US1" "T001" "front.jpg" "1"
"2" "US1" "T001" "side-left.jpg" "1"
"3" "US1" "T001" "side-right.jpg" "1"
"4" "US1" "T001" "back.jpg" "1"
"5" "CA2" "T002" "front.jpg" "2"
"6" "CA2" "T002" "side-left.jpg" "2"
"7" "CA2" "T002" "side-right.jpg" "2"
"8" "CA2" "T002" "back.jpg" "2"
"9" "UK3" "T003" "front.jpg" "3"
Sql I used
update amga a inner join amgb b on a.itemTempId = b.itemTempId
set a.itemImageName = b.itemImageName where a.itemTempId = 'T001' limit 1;
Expected results: Table amga after update
"id" "itemId" "itemTempId" "itemImageName" "itemName" "itemCountry" "userId"
"1" "US1" "T001" front.jpg "Samsung Galaxy Note 5" "US" "1"
"2" "CA2" "T002" \N "Samsung Galaxy Note 6" "CA" "2"
"3" "UK3" "T003" \N "Samsung Galaxy Note 7" "UK" "3"
Note: itemTempId is updated with front.jpg, which is the first row for itemTempId = T001 in amgb
Any help appreciated.
Update
I noticed it works if I remove the limit, and that it updates too. But is it the right way to do it? What does MySql do with the other rows in the select?
update amga a inner join amgb b on a.itemTempId = b.itemTempId
set a.itemImageName = b.itemImageName where a.itemTempId = 'T001';
Maybe you can use a subquery:
UPDATE amga a
SET a.itemImageName =
(SELECT b.itemImageName
FROM amgb b
WHERE b.itemTempId = 'T001'
ORDER BY b.id LIMIT 1)
WHERE a.itemTempId = 'T001'

Select Users who have made the most positive contributions

I thought I had this, but it's clear I don't. From the table below, I'm trying to display users who have made the most positive contributions (articles) on top, followed by the ones who didn't. The table is simple, artc_id is the article Id, artc_status is the status which shows if an article was approved or not. 0 is approved, 1 is not, then comes the user who wrote the article.
The results I'm trying to achieve are as follows:
Total Contributions Positive Contributing User
4 4 2
3 2 1
1 1 4
3 0 3
Table
"id" "artc_id" "artc_status" "artc_user" "artc_country"
"1" "1" "0" "1" "US"
"2" "2" "0" "1" "US"
"3" "3" "1" "1" "US"
"4" "4" "0" "2" "US"
"5" "5" "0" "2" "US"
"6" "6" "0" "2" "US"
"7" "7" "0" "2" "US"
"8" "8" "1" "3" "US"
"9" "9" "1" "3" "US"
"10" "10" "1" "3" "US"
"11" "11" "0" "4" "US"
The Sql I came up with
select count(artc_status) as stats , artc_user from contributions where artc_status = 0 group by artc_user order by stats desc;
I'm not having much luck getting results like I posted above. Can you please assist? This is completely beyond me.
select
count(artc_status) as stats ,
count(case when artc_status=1 then 1 end) Positive,
artc_user[Contributing User]
from
contributions
group by
artc_user
order by stats desc;
I think you just need conditional aggregation to get the two summary columns:
select count(*) as TotalContributions, count(artc_status = 0) as PositiveContributions, artc_user
from contributions
group by artc_user
order by PositiveContributions desc;

Selecting table using case clause in from clause

I have 8 table that contain different specific value for computer peripheral they are glpi_device_ram, glpi_device_hdd, glpi_device_gfxcard, glpi_device_sndcard. Each table has the same designation column in each table that contain device name. i have table glpi_computer_device that contain FK_device that contain id for each 8 table above and device type column that help me decide which table(from 8 table above) should i associate with FK_device to get designation column. I have create sql syntax but not work. I need to know whether selecting table in FROM clause using CASE clause is allowed? Here is my code
SELECT CASE device_type
WHEN "1" THEN "Casing"
WHEN "2" THEN "Processor"
WHEN "3" THEN "RAM"
WHEN "4" THEN "Harddisk"
WHEN "5" THEN "Network Card"
WHEN "6" THEN "Drive"
WHEN "7" THEN "UNKNOWN"
WHEN "8" THEN "Graphic Card"
WHEN "9" THEN "Sound Card"
WHEN "10" THEN "Other device"
END AS devicetype,
CASE device_type
WHEN "1" THEN "--"
WHEN "2" THEN "Frequency"
WHEN "3" THEN "Size"
WHEN "4" THEN "Capacity"
WHEN "5" THEN "Mac Address"
WHEN "6" THEN "Memory Size"
WHEN "7" THEN "--"
WHEN "8" THEN "Memory Size"
WHEN "9" THEN "--"
WHEN "10" THEN "--"
END AS secificity_type,
specificity,
(SELECT c.designation
FROM (SELECT CASE cd.device_type
WHEN "2" THEN "glpi_device_processor"
WHEN "3" THEN "glpi_device_ram"
WHEN "4" THEN "glpi_device_hdd"
WHEN "5" THEN "glpi_device_iface"
WHEN "6" THEN "glpi_device_drive"
WHEN "8" THEN "glpi_device_gfxcard"
WHEN "9" THEN "glpi_device_sndcard"
WHEN "10" THEN "glpi_device_pci"
END
FROM glpi_computer_device cd
WHERE cd.ID = ID ) AS c
WHERE c.ID=FK_device)
FROM `glpi_computer_device`
WHERE FK_computers = 1
no that does not work.
you should structure this as a UNION of all 8 tables - then wrap that with another select statement to get the value.