I am attempting to create several histograms that display the effects a drug has on the frequency of heart attacks.
Currently, R is organizing my data into the bins [0 - 0.5, 0.5 - 1.0, 1.0 - 1.5, etc.], but I would like for it to only use integer values: [0 - 1, 1 - 2, 2 - 3, etc.].
I have tried using the xaxt="n" argument and the axis() function. They "worked," but they did not solve the problem above. I also tried to use breaks=seq(0,5,l=6), but this converted my y-axis from frequency into density.
Here is the code for my latest two attempts:
hist(fourTrials$red_5, breaks=5, right = FALSE,
xlab = "Number of Heart Attacks",
xlim = c(0, 4), ylim = c(0,4),
main = "Experimental Group 1, n = 400", col = "light blue")
hist(fourTrials$red_5, breaks=seq(0,5,l=6), freq = F, right = FALSE,
xlab = "Number of Heart Attacks",
xlim = c(0, 4), ylim = c(0,4),
main = "Experimental Group 1, n = 400", col = "light blue",yaxs="i",xaxs="i")
Thanks for any help!
I believe that what you want is:
hist(fourTrials$red_5, breaks=0:4, freq = TRUE, right = FALSE,
xlab = "Number of Heart Attacks",
xlim = c(0, 4), ylim = c(0,4),
main = "Experimental Group 1, n = 400",
col = "lightblue", yaxs="i", xaxs="i")
Related
When creating a sunflower plot for logistic regression, the x-axis starts at 2. Can I change this behaviour to make the x-axis start at 0? I've already tried to manually change this by changing the x-axis, but that didn't make x=0 visible (see #c1).
The Sunflower Plot Image as it currently is, starting at x=2;
# EE contains the Likert Scale values
EE.min <- min(EE)
EE.max <- max(EE)
EE.x <- seq(EE.min, EE.max, length = 500)
New.EE <- data.frame(EE = EE.x)
# Creating prediction
EE.p <- predict(logit, New.EE, type = "response")
sunflowerplot(EE, cb, main = "Effort Expectancy",
xlab= "EE (5-point Likert-Scale)", ylab="Likelihood", yaxt="n", xaxt="n")
# c1:
axis(1, at = seq(0,5,0.5), labels = c(0, 0.5, 1, 1.5, 2, 2.5 , 3, 3.5, 4, 4.5, 5), las=1)
axis(2, at = seq(0,1,0.2), labels = c("No = 0", 0.2, 0.4, 0.6, 0.8, "Yes = 1"), las = 2)
abline(h = seq(0,1,0.2), lty = 2)
lines(EE.x, EE.p)
sunflowerplot has an argument xlim for the limits of the x axis.
Compare
sunflowerplot(iris$Sepal.Length, iris$Sepal.Width)
to
sunflowerplot(iris$Sepal.Length, iris$Sepal.Width, xlim = c(0, 20))
I want to create a simple one-dimensional plot in R ranging from 0 to ten, with a scale (small lines for integer values 1,2, etc.), a slightly higher line for 5 (the median) and slightly higher than all of the other for 0 and 10. Then I want to fill this plot with a few points representing values like 2, 4, 5, 6, 8, and a text above each one of them with corresponding labels (like "party voted", "closest party", "individual 1", "expert", "individual 2"). It can be smaller labels, like "PV", "CP", etc.
I would like to have control over shape and color (say in data-points 4 and 6 I have a circle filled in black but in position 2 I have a not filled square, in position 5 I have a green circle filled-in, and in position 8 I have a black triangle, also filled). I would like to have 0, 10 and 5 marked in the labels as well.
A very rough representation of what I am trying to draw is in the image below (it has all the elements I want, at least).
In this Stack Overflow question there is some code on one-dimension plot, I have tried to adapt it to what I need but didn't get to it
I've assumed from the link in the question that you are looking for a base R solution.
There may be more efficient solutions but this seems to get you where you want.
I've avoided the need for arrows by forcing the labels to run over two lines and reducing the text size on the plot so they do not overlap.
You could manage this with arrows if need be, but this seems it will need a lot of extra code.
# data
df <- data.frame(desc = c("Party voted", "Closest party", "Individual 1", "Expert", "Individual 2"),
score = c(2, 4, 5, 6, 8),
y = 1)
# add line break to labels
df$desc <- gsub("\\s", "\n", df$desc)
plot(df$score,
df$y,
# type = "o",
xlim = c(0, 10),
pch = c(1, 21,21,21, 24),
col = c("black", "black", "green", "black", "black"),
bg = c("black", "black", "green", "black", "black"),
cex = 1.5,
xaxt = "n", #remove tick marks
yaxt = "n",
ylab = '', # remove axis labels
xlab = '',
bty = "n") # remove bounding box
axis(side = 1,
0:10,
pos = df$y,
labels = FALSE,
tck = 0.02)
axis(side = 1,
0:10,
pos = df$y,
labels = c(0, rep("", 4), 5, rep("", 4), 10),
tck = -0.02)
axis(side = 1,
c(0, 5, 10),
pos = df$y,
labels = FALSE,
tck = 0.05)
axis(side = 1,
c(0, 5, 10),
pos = df$y,
labels = FALSE,
tck = -0.05)
text(x = df$score,
y = df$y,
labels = df$desc,
pos = 3,
offset = 1,
cex = 0.75)
Created on 2021-04-28 by the reprex package (v2.0.0)
I am quite new in R.
I am doing a part of my MSc thesis and wanna make some diurnal plots of for instance methane production in a period of time.
Now I a wanna see its variation in time and its correlation with another factor in the same time. Then I have two questions.
First:
How to define the xlim and ylim to increase by 2 hours. It has its own default and when I give it for example:
xlim = c(0, 23)
then it starts from 0 and goes up in 5 hours. I want it to go up in 2 hours.
Second:
How to put another variable which might be correlated to my first variable in the same time period. Let's say methane production in 23 hours could be related to oxygen consumption, just as an example. How can I put oxygen and methane in the same axis(y) against time (x)?
I will be so appreciated if you could help me with this.
Kinds,
Farhad
You can use at and labels arguments in axis function call to customize labels and tick locations.
You can use axis function with argument side = 4 to create custom y-axis on the right of you graph.
Please see the code below illustrating the above mentioned points:
set.seed(123)
x <- 0:23
df<- data.frame(
x,
ch4 = 1000 - x ^ 2,
o2 = 2000 - 2 * (x - 10) ^ 2
)
par(mar = c(5, 5, 2, 5))
with(df, plot(x, ch4,
type = "l", col = "red3",
ylab = "CH4 emission",
lwd = 3,
xlim = c(0, 23),
xlab = "",
xaxt = "n"))
axis(1, at = seq(0, 23, 2), labels = seq(0, 23, 2))
par(new = TRUE)
with(df, plot(x, o2,
pch = 16, axes = FALSE,
xlab = NA, ylab = NA, cex = 1.2))
axis(side = 4)
mtext(side = 4, line = 3, "O2 consumption")
legend("topright",
legend = c("O2", "CH4"),
lty = c(1, 0),
lwd = c(3, NA),
pch = c(NA, 16),
col = c("red3", "black"))
Output:
I don't know how to change the code so that the y-axis in the barPlot shows completely? I expect it to show up to 10 as I have a 9.2 in my data points but it shows only up to 8. Any idea what's the hack to this?
Here's the code:
And here's what it shows:
just set the ylim = c(0, 10) like the way you changed the xlim
Whatever the axis that the groups go on isn't drawn by default, so a vertical bar plot won't have x-axis; horizontal won't have y-axis. You can add that of course. Use the return value of barplot:
par(mfrow = c(2, 1))
bp <- barplot(c(8, 5), width = .5, main = 'Feature Exploration', xlim = c(0,4), ylim = c(0, 10),
ylab = 'Errors (%)', xlab = 'ML Models', col = c('gray27','orangered4'))
## this will draw the x-axis but at points 1, 2, 3, ... which is not
## where the centers of your bars are plotted; you get that info in bp
axis(1)
bp <- barplot(c(8, 5), width = .5, main = 'Feature Exploration', xlim = c(0,4), ylim = c(0, 10),
ylab = 'Errors (%)', xlab = 'ML Models', col = c('gray27','orangered4'))
## so try again with a fancy axis, bp is a matrix containing the centers
## of the plotted bars
axis(1, at = bp, labels = c('Model1','Model2'), lwd = 0, lwd.ticks = 1, tcl = -.5)
I want to add labels to the columns of my barplot. Since there are 2 groups each pair of columns will share the same label, i.e 7 labels from "dislike very much" to "like very well".
Since labels titles are quite long I intended to rotate them using the text() function but I cannot get it to display correctly. Here is the code:
A <- c(0, 1, 0, 1, 14, 44, 42)
B <- c(0, 0, 0, 2, 14, 41, 45)
x <- rbind(A, B)
dd.names <- c("Dislike very much", "Strongly dislike", "Dislike", "Neither like nor dislike", "Like", "Like well", "Like very well")
bp <- barplot(x,
beside = TRUE, # Plot the bars beside one another; default is to plot stacked bars
space=c(0.2,0.8), # Amount of space between i) bars within a group, ii) bars between groups
legend = c("Fish cake containing sugar kelp", "Control fish cake"),
args.legend = list(x = "topleft", bty = "n", inset=c(0.1, 0.1)), # bty removes the frame from the legend
xlab = "",
ylab = "Number of scores",
ylim = range(0:50), # Expand the y axis to the value 50
main = "Score results from taste experiments of fish cakes")
text(bp, par("usr")[1], pos = 1, offset = 2, labels = dd.names, adj = 0.5, srt = 25, cex = 0.8, xpd = TRUE)
IMO you're better off rotating the graph.
par(mar=c(3,8,1,1),mgp=c(1.5,.5,0))
bp <- barplot(x,
beside = TRUE,
space=c(0.2,0.8),
legend = c("Fish cake containing sugar kelp", "Control fish cake"),
args.legend = list(x = "bottom", bty = "n", inset=c(0.1, 0.1)),
ylab = "",
xlab = "Number of scores",
xlim = range(0:50), # Expand the y axis to the value 50
main = "Score results from taste experiments of fish cakes",
horiz = TRUE)
text(rep(0,length(dd.names)),bp[1,], par("usr")[3], pos = 2,
labels = dd.names, cex = 0.8, xpd = TRUE)
In an unsolicited act of evangelism, here is a ggplot solution.
library(ggplot2)
library(reshape2) # for melt(...)
library(grid) # for unit(...)
gg <- melt(data.frame(dd.names,t(x)),id="dd.names")
gg$dd.names <- with(gg,factor(dd.names,levels=unique(dd.names)))
ggplot(gg,aes(x=dd.names,y=value))+
geom_bar(aes(fill=variable),stat="identity",position="dodge")+
coord_flip()+
scale_fill_manual(name="",values=c("grey30","grey70"),
labels=c("Fish cake containing sugar kelp", "Control fish cake"))+
labs(title="Score results from taste experiments of fish cakes",
x="",y="Number of scores")+
theme_bw()+theme(legend.position = c(1,0),legend.justification = c(1,0),
legend.key.height=unit(0.8,"lines"))