I have a dataset that I would like to visualize with barplot() . My question is, why do some labels not show when appended with text() and how does one solve this issue?
For example this is my table
table(test$Freq)
2 3 4 5 6 7 8 9 10 11 12 14 16 44
6338 2544 1072 394 102 29 11 9 5 2 3 1 1 1
And the following barplot will miss the first label:
barplot(table(test$Freq))
text(x = xx, y = test$Freq, label = test$Freq, pos = 3, cex = 0.8, col = "red")
It looks like the text is being plotted outside of your graph.
Try adjusting the ylim value when you call barplot. This should solve your problem.
Related
I am working with the R programming language. Suppose I have the following data:
a = rnorm(1000,10,1)
b = rnorm(200,3,1)
c = rnorm(200,13,1)
d = c(a,b,c)
index <- 1:1400
my_data = data.frame(index,d)
I can make the following histograms of the same data by adjusting the "bin" length (via the "breaks" option):
hist(my_data, breaks = 10, main = "Histogram #1, Breaks = 10")
hist(my_data, breaks = 100, main = "Histogram #2, Breaks = 100")
hist(my_data, breaks = 5, main = "Histogram #3, Breaks = 5")
My Question: In each one of these histograms there are a different number of "bars" (i.e. bins). For example, in the first histogram there are 8 bars and in the third histogram there are 4 bars. For each one of these histograms, is there a way to find out which observations (from the original file "d") are located in each bar?
Right now, I am trying to manually do this, e.g. (for histogram #3)
histogram3_bar1 <- my_data[which(my_data$d < 5 & my_data$d > 0), ]
histogram3_bar2 <- my_data[which(my_data$d < 10 & my_data$d > 5), ]
histogram3_bar3 <- my_data[which(my_data$d < 15 & my_data$d > 10), ]
histogram3_bar4 <- my_data[which(my_data$d < 15 & my_data$d > 20), ]
head(histogram3_bar1)
index d
1001 1001 4.156393
1002 1002 3.358958
1003 1003 1.605904
1004 1004 3.603535
1006 1006 2.943456
1007 1007 1.586542
But is there a more "efficient" way to do this?
Thanks!
hist itself can provide for the solution to the question's problem, to find out which data points are in which intervals. hist returns a list with first member breaks
First, make the problem reproducible by setting the RNG seed.
set.seed(2021)
a = rnorm(1000,10,1)
b = rnorm(200,3,1)
c = rnorm(200,13,1)
d = c(a,b,c)
Now, save the return value of hist and have findInterval tell the bins where each data points are in.
h1 <- hist(d, breaks = 10)
f1 <- findInterval(d, h1$breaks)
h1$breaks
# [1] -2 0 2 4 6 8 10 12 14 16
head(f1)
#[1] 6 7 7 7 7 6
The first six observations are intervals 6 and 7 with end points 8, 10 and 12, as can be seen indexing d by f1:
head(d[f1])
#[1] 8.07743 10.26174 10.26174 10.26174 10.26174 8.07743
As for whether the intervals given by end points 8, 10 and 12 are left- or right-closed, see help("findInterval").
As a final check, table the values returned by findInterval and see if they match the histogram's counts.
table(f1)
#f1
# 1 2 3 4 5 6 7 8 9
# 2 34 130 34 17 478 512 169 24
h1$counts
#[1] 2 34 130 34 17 478 512 169 24
To have the intervals for each data point, the following
bins <- data.frame(bin = f1, min = h1$breaks[f1], max = h1$breaks[f1 + 1L])
head(bins)
# bin min max
#1 6 8 10
#2 7 10 12
#3 7 10 12
#4 7 10 12
#5 7 10 12
#6 6 8 10
I am newbie at R. Now I want to plot data (two variables) and showing regression line including the boxplot. I am able to show those data except the r square value and equation chart.
Below is my script in showing the graph
library (car)
scatterplot(FIRST_S2A_NDVI, MEAN_DRONE_NDVI,
main = "NDVI Value from Sentinel and Drone",
xlab = "NDVI Value from Sentinel",
ylab = "NDVI Value from Drone",
pch = 15, col = "black",
regLine = list(col="green"), smooth = FALSE)
The figure is like this.
Now, the final touch is to add the equation and r square value on my figure. What script do I need to write. I tried this script from Add regression line equation and R^2 on graph but still no idea how to show them.
Thanks for read and hopefully helping me in this.
p.s.
Content of my data
OBJECTID SAMPLE_GRID FIRST_S2A_NDVI MEAN_DRONE_NDVI
1 1 1 0.6411405 0.8676092
2 2 2 0.4335293 0.5697814
3 3 3 0.7350439 0.7321858
4 4 4 0.7268013 0.8271566
5 5 5 0.3638939 0.5682631
6 6 6 0.1953890 0.3168246
7 7 7 0.4841993 0.7380627
8 8 8 0.4137447 0.3239288
9 9 9 0.8219178 0.8676065
10 10 10 0.2647872 0.2296441
11 11 11 0.8126657 0.8519964
12 12 12 0.2648504 0.2465738
13 13 13 0.5992035 0.8016030
14 14 14 0.2420299 0.3933670
15 15 15 0.5059137 0.7593807
16 16 16 0.7713419 0.8026068
17 17 17 0.3762540 0.5941540
18 18 18 0.5876435 0.7763927
19 19 19 0.2491609 0.5095306
20 20 20 0.3213648 0.4456958
21 21 21 0.2101466 0.1960858
22 22 22 0.3749034 0.4956361
23 23 23 0.5712630 0.7350484
24 24 24 0.8444895 0.8577550
25 25 25 0.3331450 0.4390229
26 26 26 0.1851611 0.4573663
27 27 27 0.4914998 0.2750837
28 28 28 0.7121390 0.7780228
For adding the equation and the R squared value to your current plot. You can simply create a model with the y and x variables and format a equation and paste in over the plot using mtext function.
m <- lm(MEAN_DRONE_NDVI~FIRST_S2A_NDVI)
eq <- paste0("y = ",round(coef(m)[2],3),"x ",
ifelse(coef(m)[1]<0,round(coef(m)[1],3),
paste("+",round(coef(m)[1],3))))
mtext(eq, 3,-1)
mtext(paste0("R^2 = ",round(as.numeric(summary(m)[8]),3)), 3, -3)
You can change the variables in your model and also change the position of the text with the 2nd and 3rd arguments in the mtext function
I have a dataframe named tab of the following format:
Var1 Freq
1 5 1853
2 15 2862
3 25 7206
4 35 14890
5 45 19856
6 55 23837
7 65 16510
8 75 4729
9 85 830
I want to make a barplot and have the Freq displayed on the bar.
I have tried the following:
plot(tab$Var1, tab$Freq)
text(
x = tab$Var1,
y = tab$Freq,
labels = row.names( tab$Freq ),
adj = 0)
There seems to be two things wrong here:
The plot is showing lines instead of bars, and barplot(tab$Freq)
axis(1, xaxp = tab$Var1) gives error that Error in axis(1, xaxp = tab$Var1) : plot.new has not been called yet (PART 1 SOLVED).
Using the original plot and text function, the texts do not show up.
Thanks.
How to create the ordered bar plot in ggplot2 with both positive and negative values. Here is the data:
down -11
down -10
down -9
down -6
up 6
up 6
up 6
up 6
up 7
up 7
up 8
up 8
up 8
up 8
up 8
up 8
up 8
up 10
up 10
up 11
up 11
up 12
up 14
up 14
up 21
up 21
up 24
I have tried this code:
ggplot(GO, aes(x = d1, y = order(d2), fill = factor(d1))) +
geom_bar(stat = "identity", position = "identity", width = 0.6)
This is not working.
I would like to order the plot. Can anybody please suggest some code.
Please check out my answer for a similar question. You should set your vector up in the order you want and then use +scale_y_discrete(limits = yourOrderedData) and it should plot in your order.
I'm trying to create a stacked bar graph using ggplot 2. My data in its wide form, looks like this. The numbers in each cell are the frequency of responses.
activity yes no dontknow
Social events 27 3 3
Academic skills workshops 23 5 8
Summer research 22 7 7
Research fellowship 20 6 9
Travel grants 18 8 7
Resume preparation 17 4 12
RAs 14 11 8
Faculty preparation 13 8 11
Job interview skills 11 9 12
Preparation of manuscripts 10 8 14
Courses in other campuses 5 11 15
Teaching fellowships 4 14 16
TAs 3 15 15
Access to labs in other campuses 3 11 18
Interdisciplinary research 2 11 18
Interdepartamental projects 1 12 19
I melted this table using reshape2 and
melted.data(wide.data,id.vars=c("activity"),measure.vars=c("yes","no","dontknow"),variable.name="haveused",value.name="responses")
That's as far as I can get. I want to create a stacked bar chart with activities on the x axis, frequency of responses in the y axis, and each bar showing the distribution of the yes, nos and dontknows
I've tried
ggplot(melted.data,aes(x=activity,y=responses))+geom_bar(aes(fill=haveused))
but I'm afraid that's not the right solution
Any help is much appreciated.
You haven't said what it is that's not right about your solution. But some issues that could be construed as problems, and one possible solution for each, are:
The x axis tick mark labels run into each other. SOLUTION - rotate the tick mark labels;
The order in which the labels (and their corresponding bars) appear are not the same as the order in the original dataframe. SOLUTION - reorder the levels of the factor 'activity';
To position text inside the bars set the vjust parameter in position_stack to 0.5
The following might be a start.
# Load required packages
library(ggplot2)
library(reshape2)
# Read in data
df = read.table(text = "
activity yes no dontknow
Social.events 27 3 3
Academic.skills.workshops 23 5 8
Summer.research 22 7 7
Research.fellowship 20 6 9
Travel.grants 18 8 7
Resume.preparation 17 4 12
RAs 14 11 8
Faculty.preparation 13 8 11
Job.interview.skills 11 9 12
Preparation.of.manuscripts 10 8 14
Courses.in.other.campuses 5 11 15
Teaching.fellowships 4 14 16
TAs 3 15 15
Access.to.labs.in.other.campuses 3 11 18
Interdisciplinay.research 2 11 18
Interdepartamental.projects 1 12 19", header = TRUE, sep = "")
# Melt the data frame
dfm = melt(df, id.vars=c("activity"), measure.vars=c("yes","no","dontknow"),
variable.name="haveused", value.name="responses")
# Reorder the levels of activity
dfm$activity = factor(dfm$activity, levels = df$activity)
# Draw the plot
ggplot(dfm, aes(x = activity, y = responses, group = haveused)) +
geom_col(aes(fill=haveused)) +
theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.25)) +
geom_text(aes(label = responses), position = position_stack(vjust = .5), size = 3) # labels inside the bar segments