R Formattable apply two format to an area - r

I'm trying to use formattable awesome package and get a table with percentages and color scaled on multiple columns.
Here is the code
set.seed(123)
df <- data.frame(id = 1:10,
a = rnorm(10), b = rnorm(10), c = rnorm(10))
df$a <- percent(df$a)
df$b <- percent(df$b)
df$c <- percent(df$c)
table_with_percent_but_color_not_scaled <- formattable(df, list(a = color_tile("transparent", "pink")
, b= color_tile("transparent", "pink")
, c= color_tile("transparent", "pink")))
table_with_color_scaled_but_not_percent <- formattable(df, list(area(col = 2:4) ~ color_tile("transparent","pink")))
Problem is that table_with_color_scaled_but_not_percent don't keep the percentage format :
and table_with_percent_but_color_not_scaled don't keep the same scale for coloring the colors:
Ideally I would like to use the area functionality, since my df number of columns and name will change in my final code.
Any idea ?
Thanks!

I had the same problem a while back and had to create my own formatter. Here's the formatter with code used to create a table similar to yours. Just adjust the tags inside the style.
library(tidyverse)
library(formattable)
colorbar <- function(color = "lightgray", fun = "comma", digits = 0) {
fun <- match.fun(fun)
formatter("span", x ~ fun(x, digits = digits),
style = function(y) style(
display = "inline-block",
direction = "rtl",
"border-radius" = "4px",
"padding-right" = "2px",
"background-color" = csscolor(color),
width = percent(proportion(as.numeric(y), na.rm = TRUE))
)
)
}
set.seed(123)
df <- data.frame(id = as.factor(1:10),
a = rnorm(10), b = rnorm(10), c = rnorm(10)) %>%
mutate_if(is.numeric, percent)
tbl <- df %>%
formattable(list(area(col = 2:4) ~ colorbar(color = "pink", fun = "percent", digits = 2))) %>%
as.htmlwidget()
If you have questions, let me know!

Related

How to cluster with Plotly and color based off of a column in R

I am trying to use plotly to scatter the results of applying kmeans to dataframe and I want to color the scattered points based on the results of the kmeans. I am following this this link to use plotly but plotly is not coloring the scattered plots as I would like. Here is my code.
library(plotly)
library(data.table)
library(tidyverse)
# generate the data
sample1_x <- rnorm(n = 1000, mean = 0, sd = 1)
sample1_y <- rnorm(n = 1000, mean = 1, sd = 1)
sample2_x <- rnorm(n = 1000, mean = 5, sd = 1)
sample2_y <- rnorm(n = 1000, mean = 3, sd = 1)
# store the data in dataframes
df1 <- data.frame(sample1_x, sample1_y)
df2 <- data.frame(sample2_x, sample2_y)
df <- rbind(as.data.table(df1), as.data.table(df2), use.names = FALSE)
clusts <- kmeans(df, 2, 5)
clusts <- array(unlist(clusts), dim = c(2000, 1, 1))
df <- df %>%
add_column(clusters = clusts)
# rename the columns
colnames(df)[1: 2] <- c("col1", "col2")
# plot
fig <- plot_ly(data = df,
x = ~col1, y = ~col2,
color = ~clusters,
colors = c("red", "blue"),
type = "scatter", mode = "markers")
fig
is what plotly is returning, but what I want is .
The problem is that your clusters column is an <array> instead of a <num>.
set.seed(1)
df <- data.frame(col1 = c(rnorm(1000, 0), rnorm(1000, 5)),
col2 = c(rnorm(1000, 1), rnorm(1000, 3)))
setDT(df)
clusts <- kmeans(df, 2, 5)
df[, clusters := clusts$cluster]
plot_ly(data = df,
x = ~col1, y = ~col2,
color = ~clusters,
colors = c("red", "blue"),
type = "scatter", mode = "markers")

Consistency in the color of groups in 'plotly' plots in R when making many plots

I have the following data:
df1 <- data.frame(col1 = rep(LETTERS[1:3], each = 4), col2 = rnorm(12), col3 = runif(12), col4 = rep(c("Fred", "Bob"), each = 6))
df1_list <- split(df1, df1$col1)
I'm trying to make a separate plot for each list element and arrange them in the same figure:
lapply(df1_list, function (arg1) {
plotly::plot_ly(arg1, x = ~col2, y = ~col3, color = ~col4) %>%
layout(showlegend = T)
}) %>%
subplot()
The problem is that the colors are not consistent across each plot. I'd like points representing Fred always to be the same color, and the same should go for points representing Bob.
Is there a way to ensure groups get the same color across all these plots?
Thanks!
One option would be to use a named color vector which assigns a color to each name like so:
set.seed(123)
df1 <- data.frame(col1 = rep(LETTERS[1:3], each = 4),
col2 = rnorm(12),
col3 = runif(12),
col4 = rep(c("Fred", "Bob"), each = 6))
df1_list <- split(df1, df1$col1)
colors <- RColorBrewer::brewer.pal(3, "Set2")[c(1, 3)]
names(colors) <- c("Fred", "Bob")
library(plotly)
lapply(df1_list, function (arg1) {
plotly::plot_ly(arg1, x = ~col2, y = ~col3, color = ~col4, colors = colors) %>%
layout(showlegend = T)
}) %>%
subplot()

Plot a list using R

I would like to know how to plot a list.
Now I have a list
[[1977]] keyword1, keyword2, keyword3, ...
[[1978]] keyword2, keyword5, ...
...
[[2018]] keyword1, keywords3, ...
length(mylist) = 2018
lengts(mylist) = 0,0,0,0,0,......
dput(head(mylist)) = list(NULL, NULL, NULL, NULL, NULL, NULL)
And I would like to plot it using keywords' frequencies as the y-axis and 1977~2018 as the x-axis.
So it should have many lines equal to the number of the keywords. Does anyone have any idea?
Try this example:
# example data
set.seed(1); myList <- list(sample(LETTERS[1:3], 10, replace = TRUE),
sample(LETTERS[1:3], 10, replace = TRUE),
sample(LETTERS[1:3], 10, replace = TRUE),
sample(LETTERS[1:3], 10, replace = TRUE),
sample(LETTERS[1:3], 10, replace = TRUE))
names(myList) <- 1977:1981
library(ggplot2)
library(dplyr)
plotDat <- stack(myList) %>%
mutate(myYears = as.numeric(as.character(ind)),
myWords = values) %>%
group_by(myYears, myWords) %>%
summarise(myCount = n())
ggplot(plotDat, aes(x = myYears, y = myCount, col = myWords)) +
geom_line()
You can probably use data.table::rbindlist() to create a long data.table. Summarise to a frequency-table to plot with ggplot-functions
# using example data from #zx8754's answer.
library( data.table )
library( ggplot2 )
dt <- data.table::rbindlist( lapply( myList, as.data.table ), idcol = "year" )
dt <- dt[, .N, by = list(year, V1) ]
ggplot( data = dt, aes( x = year, y = N, group = V1, fill = V1 )) + geom_col( color = "black" )

Replacing values across a data frame's variables from a list of nested data frames

Let's presume I have the following dataframe:
df <- data.frame(x = rnorm(10), y = rnorm(10), z = rnorm(10))
And I would like to replace the values in the variables by their corresponding data frame and variable names in the following list:
replace_df <- list(x = data.frame(x = 1:10),
y = data.frame(y = 11:20),
z = data.frame(z = 21:30))
How would I do that using dplyr?
I feel like my issue is related to this Q&A, but I haven't been able to implement the answers to that question correctly to my situation.
I've attempted the below, among others, without success:
library(tidyverse)
variables <- c("x", "y", "z")
df %>%
mutate_at(vars(variables), funs(replace_df[[.]][[.]]))
The "dumb" way would be the following:
df %>%
mutate(x = replace_df[["x"]][["x"]],
y = replace_df[["y"]][["y"]],
z = replace_df[["z"]][["z"]])
You need to use expr! I am not sure if the subsetting will work as you tried above, but I was able to get the correct output by making a simple function and passing in an argument that was wrapped in expr()
df <- data.frame(x = rnorm(10), y = rnorm(10), z = rnorm(10))
replace_df <- list(x = data.frame(x = 1:10),
y = data.frame(y = 11:20),
z = data.frame(z = 21:30))
my_func <- function(string) {
return(
replace_df[[string]][[string]]
)
}
df %>%
mutate_at(vars(x, y, z), funs(my_func(expr(.))))

Hover on title of Highcharter graph.

I'm trying to add like an information box on hover on title of the highcharter graph. When the user hovers over title, it should show some information about the graph. Can this be achieved using Highcharter in R ?
Thank You! Here is a sample code to which I want to add hover property for title.
library(dplyr)
library(stringr)
library(purrr)
n <- 5
set.seed(123)
colors <- c("#d35400", "#2980b9", "#2ecc71", "#f1c40f", "#2c3e50", "#7f8c8d")
colors2 <- c("#000004", "#3B0F70", "#8C2981", "#DE4968", "#FE9F6D", "#FCFDBF")
df <- data.frame(x = seq_len(n) - 1) %>%
mutate(
y = 10 + x + 10 * sin(x),
y = round(y, 1),
z = (x*y) - median(x*y),
e = 10 * abs(rnorm(length(x))) + 2,
e = round(e, 1),
low = y - e,
high = y + e,
value = y,
name = sample(fruit[str_length(fruit) <= 5], size = n),
color = rep(colors, length.out = n),
segmentColor = rep(colors2, length.out = n)
)
create_hc <- function(t) {
dont_rm_high_and_low <- c("arearange", "areasplinerange",
"columnrange", "errorbar")
is_polar <- str_detect(t, "polar")
t <- str_replace(t, "polar", "")
if(!t %in% dont_rm_high_and_low) df <- df %>% select(-e, -low, -high)
highchart() %>%
hc_title(text = paste(ifelse(is_polar, "polar ", ""), t, '\u2370'),
style = list(fontSize = "15px")) %>%
hc_chart(type = t,
polar = is_polar) %>%
hc_xAxis(categories = df$name) %>%
hc_add_series(df, name = "Fruit Consumption", showInLegend = FALSE)
}
hcs <- c("line") %>%
map(create_hc)

Resources