Geom_bar plot only shows one bar per plot - r

I am trying to compare two NBA players in various stats by using geom_bar but for some reason it is only plotting one bar per stat. I would like to have both bars on each plot to see how the two players compare to each other, or in other words a red and a blue on every plot
This is what I have tried
url <- paste0('https://www.basketball-reference.com/leagues/NBA_2022_per_game.html')
# scrape the url
webpage <- read_html(url)
hp_table <-
html_nodes(webpage, "table")
nba_table <- html_table(hp_table)
# convert to dataframe
df <- as.data.frame(nba_table)
df <- df[,-1]
df
longer <- df %>% pivot_longer(-Player)
player_list <- c('Precious Achiuwa', 'Steven Adams')
filtered <- longer %>% filter(Player == player_list)
ggplot(filtered, aes(x = Player, y = value)) +
geom_bar(aes(fill = Player),
stat = 'identity')+
facet_wrap(~name, scales = 'free_y')+
theme(axis.text.x = element_blank())

url <- paste0('https://www.basketball-reference.com/leagues/NBA_2022_per_game.html')
# scrape the url
webpage <- read_html(url)
hp_table <-
html_nodes(webpage, "table")
nba_table <- html_table(hp_table)
# convert to dataframe
df <- as.data.frame(nba_table)
df <- df[,-1]
df <- df %>% pivot_longer(cols = Pos:PTS) %>%
mutate(value = as.numeric(value)) %>%
filter(!is.na(value)) %>%
filter(Player %in% c("Precious Achiuwa", "Steven Adams"))
ggplot(df, aes(x = Player, fill = Player, y = value)) +
geom_bar(stat = "identity", position = "dodge") +
facet_wrap(~name, "free_y") +
theme(axis.text.x = element_blank())
Your pivot_longer was incorrectly specified
Even if it was you would have had overlapping bars because you didn't specify position = "dodge" in your ggplot2 call.

Related

Mixing stacked and unstacked bars in single graph

I'm trying to mix stacked and unstacked bars in one graph.
Here is sample code:
Indicators <- c("Z","X","C","NO C","NA C","LOW C","HIGH C","D","E","F","G","H","LOW H","MED H","HIGH H",
"I","LOW I","MED I","HIGH I","J","LOW J","MED J","HIGH J")
Class_1 <- c(0.44,0.01,"",0.6,0.13,0.11,0.16,0.08,0.01,0.14,0.21,"",0.55,
0.23,0.22,"",0.4,0.31,0.29,"",0.41,0.23,0.36)
data <- data.frame(Indicators,Class_1)
How can I make a graph with both unstacked and stacked bars? I really appreciate all the help there is! Thanks!
Basically you want a stacked barchart even if for some categories there is nothing to stack. To this end you have to do some data wrangling and cleaning like getting rid of the empty value rows and splitting the Indicators column in two:
library(dplyr)
library(ggplot2)
library(tidyr)
data1 <- data |>
filter(Class_1 != "") |>
mutate(Class_1 = as.numeric(Class_1)) |>
separate(Indicators, into = c("level", "which"), fill = "left") |>
replace_na(list(level = "Total"))
ggplot(data1, aes(which, Class_1, fill = level)) +
geom_col()
Update II:
library(tidyverse)
my_pattern1 <- c("No|Non|Low-risk|High-risk|Low|Medium|High")
data %>%
filter(Class_1 != "") %>%
mutate(x = case_when(str_detect(Indicators, 'CSA|childhood sexual abuse') ~ "Childhood sexual abuse",
str_detect(Indicators, 'discrimination') ~ "discrimination"),
y = str_extract(Indicators, my_pattern1)) %>%
mutate(z = str_remove_all(Indicators, my_pattern1)) %>%
mutate(y= ifelse(is.na(y), "Total", y)) %>%
ggplot(aes(x = z, y = as.numeric(Class_1), fill= y))+
geom_bar(stat = "identity", position = "stack")+
theme(axis.text.x = element_text(angle = 45, vjust = 0.5, hjust=1))
Update: (#camille is right. I now adapted my answer and removed the first one)
library(tidyverse)
data %>%
separate(Indicators, c("Indicators_1", "Indicators_2")) %>%
mutate(Indicators_3 = ifelse(is.na(Indicators_2), "Total", Indicators_1),
Indicators_2 = coalesce(Indicators_2, Indicators_1)) %>%
filter(Class_1 != "") %>%
ggplot(aes(x = Indicators_2, y = as.numeric(Class_1), fill= Indicators_3))+
geom_bar(stat = "identity", position = "stack")

Sorting Y-axis of barplot based on the decresing value of last facet grid in ggplot2

Question:
I am trying to sort the Y-axis of the barplot based on the decreasing value of the last facet group "Step4" with having a common Y-axis label. There are suggestions for ordering all facet groups within themselves but how to do with the common y-axis label and values of one facet group. I have attached a sample data and code for the initial plot to understand the question.
Thanks in advance.
Data:
Download the sample data here
Code:
library(ggplot2)
library(reshape2)
#reading data
data <- read.csv(file = "./sample_data.csv", stringsAsFactors = TRUE)
#reshaping data in longer format using reshape::melt
data.melt <- melt(data)
#plotting the data in multi-panel barplot
ggplot(data.melt, aes(x= value, y=reorder(variable, value))) +
geom_col(aes(fill = Days), width = 0.7) +
facet_grid(.~step, scales = "free")+
theme_pubr() +
labs(x = "Number of Days", y = "X")
Graph: Barplot Graph for the sample data
Summarise the values for last 'step' and extract the levels from the data.
library(dplyr)
library(ggplot2)
lvls <- data.melt %>%
arrange(step) %>%
filter(step == last(step)) %>%
#Or
#filter(step == 'Step4') %>%
group_by(variable) %>%
summarise(sum = sum(value)) %>%
arrange(sum) %>%
pull(variable)
data.melt$variable <- factor(data.melt$variable, lvls)
ggplot(data.melt, aes(x= value, y= variable)) +
geom_col(aes(fill = days), width = 0.7) +
facet_grid(.~step, scales = "free")+
theme_pubr() +
labs(x = "Number of Days", y = "X")

Same variables from 2 separate data.frames sided by side in ggplot2

I want to plot the exact same variable names (ses & math) from 2 separate data.frames (dat1 & dat2) but side by side so I can visually compare them.
I have tried the following but it places both data.frames on top of each other.
Is there a function within ggplot2 to plot ses vs. math from dat1 and the same from dat2 side by side and placed on the same axes scales?
library(ggplot2)
dat1 <- read.csv('https://raw.githubusercontent.com/rnorouzian/e/master/hsb.csv')
dat2 <- read.csv('https://raw.githubusercontent.com/rnorouzian/e/master/sm.csv')
ggplot(dat1, aes(x = ses, y = math, colour = factor(sector))) +
geom_point() +
geom_point(data = dat2, aes(x = ses, y = math, colour = factor(sector)))
You can try faceting combining the two datasets :
library(dplyr)
library(ggplot2)
list(dat1 = dat1 %>%
select(sector,ses, math) %>%
mutate(sector = as.character(sector)) ,
dat2 = dat2 %>% select(sector,ses, math)) %>%
bind_rows(.id = 'name') %>%
ggplot() +
aes(x = ses, y = math, colour = factor(sector)) +
geom_point() +
facet_wrap(.~name)
Another option is to create list of plots and arrange them with grid.arrange :
list_plots <- lapply(list(dat1, dat2), function(df) {
ggplot(df, aes(x = ses, y = math, colour = factor(sector))) + geom_point()
})
do.call(gridExtra::grid.arrange, c(list_plots, ncol = 2))

Sort ggplot facet_wrap by color?

I would like to sort by ggplot facet_wrap by color.
For example, in this demo code, the color corresponds to groups A, B, C. I am looking to have all the red plots next to each other, and same for the blue and green plots.
I tried sorting my data by group but ggplot seems to switch the order when plotting.
library(tidyverse)
set.seed(42)
# Generate example data frame
id <- 1:15
data <- map(id, ~rnorm(10))
date <- map(id, ~1:10)
group <- map_chr(id, ~sample(c('a','b','c'), size=1))
df <- tibble(id=id, data=data, date=date, group=group) %>% unnest(cols = c(data, date))
# Generate plot
df %>%
arrange(group) %>%
ggplot(mapping = aes(x=date, y=data, color=group)) +
geom_line() +
geom_point() +
facet_wrap(~ id)
This could help:
library(tidyverse)
set.seed(42)
# Generate example data frame
id <- 1:15
data <- map(id, ~rnorm(10))
date <- map(id, ~1:10)
group <- map_chr(id, ~sample(c('a','b','c'), size=1))
df <- tibble(id=id, data=data, date=date, group=group) %>% unnest(cols = c(data, date))
df2 <- df %>% mutate(id=factor(id))%>%
group_by(group) %>%
mutate(N = n()) %>%
ungroup() %>%
mutate(id = fct_reorder(id, N))
# Generate plot
df2 %>%
arrange(group) %>%
ggplot(mapping = aes(x=date, y=data, color=group)) +
geom_line() +
geom_point() +
facet_wrap(~ id)
This would be a way (would have to get rid of the double title though):
df %>%
arrange(group) %>%
ggplot(mapping = aes(x=date, y=data, color=group)) +
geom_line() +
geom_point() +
facet_wrap(~ group + id)

bar chart of row freq ggplot2

I have the following data:
dataf <- read.table(text = "index,group,taxa1,taxa2,taxa3,total
s1,g1,2,5,3,10
s2,g1,3,4,3,10
s3,g2,1,2,7,10
s4,g2,0,4,6,10", header = T, sep = ",")
I'm trying to make a stacked bar plot of the frequences of the data so that it counts across the row (not down a column) for each index (s1,s2,s3,s4) and then for each group (g1,g2) of each taxa. I'm only able to figure out how to graph the species of one taxa but not all three stacked on each other.
Here are some examples of what I'm trying to make:
These were made on google sheets so they don't look like ggplot but it would be easier to make in r with ggplot2 because the real data set is larger.
You would need to reshape the data.
Here is my solution (broken down by plot)
For first plot
library(tidyverse)
##For first plot
prepare_data_1 <- dataf %>% select(index, taxa1:taxa3) %>%
gather(taxa,value, -index) %>%
mutate(index = str_trim(index)) %>%
group_by(index) %>% mutate(prop = value/sum(value))
##Plot 1
prepare_data_1 %>%
ggplot(aes(x = index, y = prop, fill = fct_rev(taxa))) + geom_col()
For second plot
##For second plot
prepare_data_2 <- dataf %>% select(group, taxa1:taxa3) %>%
gather(taxa,value, -group) %>%
mutate(group = str_trim(group)) %>%
group_by(group) %>% mutate(prop = value/sum(value))
##Plot 2
prepare_data_2 %>%
ggplot(aes(x = group, y = prop, fill = fct_rev(taxa))) + geom_col()
##You need to reshape data before doing that.
dfm = melt(dataf, id.vars=c("index","group"),
measure.vars=c("taxa1","taxa2","taxa3"),
variable.name="variable", value.name="values")
ggplot(dfm, aes(x = index, y = values, group = variable)) +
geom_col(aes(fill=variable)) +
theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.25)) +
geom_text(aes(label = values), position = position_stack(vjust = .5), size = 3) + theme_gray()

Resources