Issue in creating polygon in ggplot in R - r

Why does my polygon look like two triangles instead of a box? Can some help explain how I can turn the polygon into a box?
data <- structure(list(AREA = c("a", "a", "b", "b"), Lat = c(43.68389835,
43.68389835, 44.3395883, 44.3395883), Long = c(-88.22909367,
-88.99888743, -88.22909367, -88.99888743)), row.names = c(NA,
-4L), spec = structure(list(cols = list(AREA = structure(list(), class = c("collector_character",
"collector")), Lat = structure(list(), class = c("collector_double",
"collector")), Long = structure(list(), class = c("collector_double",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), delim = ","), class = "col_spec"), problems = <pointer: 0x000002548f014500>, class = c("spec_tbl_df",
"tbl_df", "tbl", "data.frame"))
Code:
library(tidyverse)
ggplot() + geom_polygon(data=data, mapping=aes(x=Long, y=Lat))

Currently geom_polygon draws the polygon in exactly the order of the points as given in data. To have a closed polygon, you need to order your points appropriately, either clockwise or anti-clockwise.
We can do this by calculating the angle relative to the lat/long centre, and then order points according to that angle.
library(tidyverse)
data %>%
mutate(angle = atan2(Lat - mean(Lat), Long - mean(Long))) %>%
arrange(desc(angle)) %>%
ggplot() +
geom_polygon(aes(x = Long, y = Lat))

Related

Count edges using the adjacency matrix

Based on the adjacency matrix, I would like to count the number of unique edges in a network. In the below example I coloured the unique edges between the different nodes. But I don't know how to proceed.
Desired output:
Sample data
structure(list(...1 = c("m1", "m2", "m3", "m4"), m1 = c(0.2,
0.2, 0.2, 0.3), m2 = c(0.1, 0.2, 0.2, 0.6), m3 = c(0.5, 0.2,
1, 0), m4 = c(0.3, 0, 0, 0.1)), row.names = c(NA, -4L), spec = structure(list(
cols = list(...1 = structure(list(), class = c("collector_character",
"collector")), m1 = structure(list(), class = c("collector_double",
"collector")), m2 = structure(list(), class = c("collector_double",
"collector")), m3 = structure(list(), class = c("collector_double",
"collector")), m4 = structure(list(), class = c("collector_double",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), delim = ","), class = "col_spec"), class = c("spec_tbl_df",
"tbl_df", "tbl", "data.frame"))
Assuming that this is an undirected graph such that 0 indicates no edge and a positive number indicates an edge, convert the input DF to a logical matrix and from that to an igraph object. Then get its edges and the names of those edges. (Another possible output is by using as_edgelist(g) to get a 2 column matrix such that each row defines an edge.)
If it were intended that the graph be directed then replace "undirected" with "directed" and in that case a character vector of 13 edge names will be produced instead of the 9 undirected edges shown below.
library(igraph)
m <- as.matrix(DF[-1])
rownames(m) <- colnames(m)
g <- graph_from_adjacency_matrix(m > 0, "undirected")
e <- E(g)
attr(e, "vnames")
## [1] "m1|m1" "m1|m2" "m1|m3" "m1|m4" "m2|m2" "m2|m3" "m2|m4" "m3|m3" "m4|m4"
Alternately as a pipeline
library(igraph)
library(tibble)
DF %>%
column_to_rownames("...1") %>%
as.matrix %>%
sign %>%
graph_from_adjacency_matrix("undirected") %>%
E %>%
attr("vnames")
## [1] "m1|m1" "m1|m2" "m1|m3" "m1|m4" "m2|m2" "m2|m3" "m2|m4" "m3|m3" "m4|m4"
The graph of g looks like this. (If "directed" had been chosen above then the edges would have arrowheads on them.)
set.seed(123)
plot(g)
Note
DF <-
structure(list(...1 = c("m1", "m2", "m3", "m4"), m1 = c(0.2,
0.2, 0.2, 0.3), m2 = c(0.1, 0.2, 0.2, 0.6), m3 = c(0.5, 0.2,
1, 0), m4 = c(0.3, 0, 0, 0.1)), row.names = c(NA, -4L), spec = structure(list(
cols = list(...1 = structure(list(), class = c("collector_character",
"collector")), m1 = structure(list(), class = c("collector_double",
"collector")), m2 = structure(list(), class = c("collector_double",
"collector")), m3 = structure(list(), class = c("collector_double",
"collector")), m4 = structure(list(), class = c("collector_double",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), delim = ","), class = "col_spec"), class = c("spec_tbl_df",
"tbl_df", "tbl", "data.frame"))

Loop in tidyverse

I am learning tidyverse() and I am using a time-series dataset, and I selected columns that start with sec. What I would like basically to identify those values from columns that equal 123, keep these and have the rest replace with 0. But I don't know how to loop from sec1:sec4. Also how can I sum() per columns?
df1<-df %>%
select(starts_with("sec")) %>%
select(ifelse("sec1:sec4"==123, 1, 0))
Sample data:
structure(list(sec1 = c(1, 123, 1), sec2 = c(123, 1, 1), sec3 = c(123,
0, 0), sec4 = c(1, 123, 1)), spec = structure(list(cols = list(
sec1 = structure(list(), class = c("collector_double", "collector"
)), sec2 = structure(list(), class = c("collector_double",
"collector")), sec3 = structure(list(), class = c("collector_double",
"collector")), sec4 = structure(list(), class = c("collector_double",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), delim = ","), class = "col_spec"), row.names = c(NA,
-3L), class = c("spec_tbl_df", "tbl_df", "tbl", "data.frame"))
I think you would have to use mutate and across to accomplish this. below you will mutate across each column starting with sec and then keep all values that are 123 and replace all others with 0.
df1<-df %>%
select(starts_with("sec")) %>%
mutate(across(starts_with("sec"),.fns = function(x){ifelse(x == 123,x,0)}))

Boxplot across three timepoints in ggplot

I would like boxplots with all three timepoints in my data on the same plot
Data:
df<-
structure(list(ID = c("ED_001", "ED_002", "ED_003", "ED_004",
"ED_005"), Color = c("Black", "White", "Black", "Black", "White"
), Data_t1 = c(150, 159, 160, 154, 187), Data_t2 = c(123, 124,
125, 126, 140), Data_t3 = c(133, 135, 145, 150, 153)), class = c("spec_tbl_df",
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -5L), spec = structure(list(
cols = list(ID = structure(list(), class = c("collector_character",
"collector")), Color = structure(list(), class = c("collector_character",
"collector")), Data_t1 = structure(list(), class = c("collector_double",
"collector")), Data_t2 = structure(list(), class = c("collector_double",
"collector")), Data_t3 = structure(list(), class = c("collector_double",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), skip = 1), class = "col_spec"))
I can plot the first timepoint easily enough:
df %>%
ggplot(. , aes(x = as.factor(Color), y = Data_t1)) +
geom_boxplot()
But how do I also plot Data_t2 and Data_t3? I don't think facet_wrap is the right approach. Do I group_by timepoint, and if so how? I would prefer a dplyr solution if possible rather than melting the data into long format as I always come unstuck with long format. Thanks
It looks like you’ve noticed it’s easiest to work with the data if it’s in long format. Here’s the method with tidyr. I then use a facet to separate the different groups. What facet you use depends on how you want to compare them.
library(tidyverse)
df %>%
pivot_longer(starts_with("Data")) %>%
ggplot(. , aes(y = value, x= Color, group = Color)) +
geom_boxplot() +
facet_grid(~name)
If you really wanted them all on the same plot without facets, you could create a dummy variable. You could play around with factors to order them how you wish.
df %>%
pivot_longer(starts_with("Data")) %>%
mutate(group_var = paste0(name, " - ", Color)) %>%
ggplot(. , aes(y = value, x= group_var, group = group_var)) +
geom_boxplot()
Created on 2022-01-14 by the reprex package (v2.0.1)

Visualize bubbles on a map, using hc_add_series_map() instead of hcmap()

I am trying to visualize a bubble map, using highcharter.
I did it perfectly, using this code
library(highcharter)
library(tidyverse)
hcmap("custom/africa") %>%
hc_add_series(data = fake_data, type = "mapbubble", maxSize = '10%', color =
"Red", showInLegend = FALSE) %>%
hc_legend(enabled = FALSE)
My data
> dput(fake_data)
structure(list(country = c("DZ", "CD", "ZA", "TZ"), lat = c(28.033886,
-4.038333, -30.559482, -6.369028), lon = c(1.659626, 21.758664,
22.937506, 34.888822), name = c("Algeria", "Congo, Dem. Rep",
"South Africa", "Tanzania"), z = c(20, 5, 10, 1)), class = c("spec_tbl_df",
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -4L), spec =
structure(list(
cols = list(country = structure(list(), class = c("collector_character",
"collector")), lat = structure(list(), class = c("collector_double",
"collector")), lon = structure(list(), class = c("collector_double",
"collector")), name = structure(list(), class = c("collector_character",
"collector")), z = structure(list(), class = c("collector_double",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), skip = 1), class = "col_spec"))
External geo data for Africa originally comes from this source and used with hcmap().
But I transform it into RDS and use locally. Available here.
My problem that I cannot use my code and external data due to corporate IT security restrictions. I cannot deploy this code with Shiny/RMarkdown on Connect, it is blocked.
So my solution currently
Use the same data in RDS format
africa_map_data <- readRDS("africa_map_data.RDS")
And use the hc_add_series_map() with local data instead of hcmap().
highchart() %>%
hc_add_series_map(
map = africa_map_data,
df = fake_data,
value = "z",
joinBy = c("hc-a2", "country"),
type = "mapbubble",
maxSize = '10%',
color = "Red"
)
But it does not work well, I get a mess.
How to create a bubble map with hc_add_series_map() (or any other way) without 'hcmap' and pulling external data.
Thanks!

plot_ly is scaling bubble within color - need absolute scale

I am trying to create a bubble chart that plots 2 variables, X and Y, on the x and y axes. There is a 3rd variable, Size (which I am indicating with the size of the circle/bubble), and a 4th variable (Store Type, which I am indicating with color).
plot_ly appears to be scaling the bubbles within color (so that bubbles that should be of similar size are actually very different).
I would like to scale all the bubble relative to each other in terms of Size, regardless of Store Type or Color. I am using RStudio, most recent version as of 6/23/2017
Here is the data set:
structure(list(Code = 1:16, Store = c("A", "B", "B", "B", "B",
"B", "B", "B", "B", "B", "B", "B", "H", "H", "H", "L"), X = c(0.551644853,
0.475211345, 0.507242364, 0.439768021, 0.46672606, 0.424724417,
0.431189134, 0.456000812, 0.422705703, 0.412122806, 0.389925153,
0.466706775, 0.541410342, 0.580674207, 0.533852255, 0.445491296
), Y = c(0.937149903, 0.250231202, 0.434706987, 0.500365364,
0.342481711, 0.199052594, 0.18707338, 0.107246187, 0.109985903,
0.157119571, 0.10706856, 0.069265636, 1.316429676, 0.703730168,
0.379612334, 1.728825132), Size = c(2642.3635, 2177.152838, 1530.361042,
1084.561203, 1057.180728, 1021.145556, 610.5342105, 449.325566,
311.9607609, 288.4075641, 211.5126293, 190.3996606, 2853.952619,
2286.511829, 973.8094512, 332.2424444)), .Names = c("Code", "Store",
"X", "Y", "Size"), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,
-16L), spec = structure(list(cols = structure(list(Code = structure(list(), class = c("collector_integer",
"collector")), Store = structure(list(), class = c("collector_character",
"collector")), X = structure(list(), class = c("collector_double",
"collector")), Y = structure(list(), class = c("collector_double",
"collector")), Size = structure(list(), class = c("collector_double",
"collector"))), .Names = c("Code", "Store", "X", "Y", "Size")),
default = structure(list(), class = c("collector_guess",
"collector"))), .Names = c("cols", "default"), class = "col_spec"))
...and here is my current code:
plot_ly(data = q, x = q$X, y = q$Y, text = paste("Size: ", q$Size), mode = "markers", color = q$Store, size = q$Size)
Thanks in advance for your help!

Resources