How to mirror the outer positions with the variable with R - r

I have a data frame:
tes <- data.frame(x = c(1, 1, 1, 2, 2, 2, 3, 3, 3),
y = c(1, 2, 3, 1, 2, 3, 1, 2, 3),
d = c(10, 20, 30, 100, 11, 12, 403, 43, 21))
They look like this on the plot
ggplot(aes(x = x, y = y), data = tes) + geom_point(aes(color = factor(d)), size = 5)
I'd like to "mirror the outer rows in this data to obtain such data and plot
tes1 <- data.frame(x = c(0, 0, 0, 0,0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4),
y = c(0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4),
d = c(10, 10, 20, 30, 30, 10, 10, 20, 30, 30, 100, 100, 11, 12, 12, 403, 403, 43, 21, 21, 403, 403, 43, 21, 21))
ggplot(aes(x = x, y = y), data = tes1) + geom_point(aes(color = factor(d)), size = 4)

Does this do what you're after?
Explanation: We first convert tes into a flattened table with ftable(xtabs(...). Then we simply replicate the first and last column, and first and last row. We then give new column and row names to reflect the extra "flanking" rows and columns, and finally convert back to a long dataframe with data.frame(table(...))
# Convert to table then matrix
m <- ftable(xtabs(d ~ x + y, data = tes));
class(m) <- "matrix";
# Replicate first and last column/row by binding to the beginning
# and end, respectively of the matrix
m <- cbind(m[, 1], m, m[, ncol(m)]);
m <- rbind(m[1, ], m, m[nrow(m), ]);
# Set column/row names
rownames(m) <- seq(min(tes$x) - 1, max(tes$x) + 1);
colnames(m) <- seq(min(tes$y) - 1, max(tes$y) + 1);
# Convert back to long dataframe
tes.ext <- data.frame(as.table(m));
colnames(tes.ext) <- colnames(tes);
# Plot
ggplot(aes(x = x, y = y), data = tes.ext) + geom_point(aes(color = factor(d)), size = 5)
Data
tes <- data.frame(x = c(1, 1, 1, 2, 2, 2, 3, 3, 3),
y = c(1, 2, 3, 1, 2, 3, 1, 2, 3),
d = c(10, 20, 30, 100, 11, 12, 403, 43, 21))

Related

geom_bar(), Y-axis goes way above data value

I am trying to visualize a data frame from a survey. I'm currently trying to plot a barplot with geom_bar(), that takes in "Life Satisfaction" as the y-axis, and "Family Values" as the x-axis. Note that the survey answer for Life Satisfaction is 1(very unsatisfied) to 10(very satisfied).
But for some reason when I try to plot this barplot, the y-axis goes way above 10, and I don't understand why.
This is my code:
df1 %>%
filter(df1$B_COUNTRY_ALPHA == "PAK") %>%
drop_na(Q49) %>%
ggplot(aes(x = Q1, y = Q49, fill = B_COUNTRY_ALPHA)) +
geom_bar(stat = "identity") +
labs(x = "Family Value",
y = "Life Satisfaction")
This is the graph that I get when I run it:
This is the first 20 rows of data that I want to work with:
On a side note: I was thinking of finding the mean of the Life Satisfaction data and maybe that will make the plot make sense but I am not sure how to do that
#GregorThomas I followed your instructions and I got this.
structure(list(B_COUNTRY_ALPHA = c("PAK", "PAK", "PAK", "PAK",
"PAK", "PAK", "PAK", "PAK", "PAK", "PAK", "PAK", "PAK", "PAK",
"PAK", "PAK", "PAK", "PAK", "PAK", "PAK", "PAK"), Q49 = c(7,
10, 10, 5, 1, 6, 6, 10, 10, 10, 4, 4, 8, 10, 10, 10, 10, 9, 10,
8), Q1 = c(1, 2, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1), Q2 = c(1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 2, 1,
4, 1, 2, 2, 2), Q3 = c(2, 2, 1, 1, 3, 1, 2, 2, 2, NA, 2, 4, 1,
1, 2, 2, 4, 2, 4, 2), Q4 = c(3, 4, 2, 4, 2, 3, 4, 2, 1, 4, 4,
4, 4, 1, 3, 4, 3, 4, 4, 2), Q5 = c(1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 1, 2, 1, 1, 1, 4, 1, 1, 4), Q6 = c(1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 4), Q57 = c(2, 2, 2, 1, 1,
1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 2, 2, 1), Q106 = c(7, 5,
10, 4, 10, 7, 1, 10, 10, 10, 1, 10, 1, 10, 10, 10, 9, 4, 10,
6), Q107 = c(7, 6, 5, 5, 10, 3, 1, 10, 10, NA, 1, 1, 1, 10, 3,
10, 10, 8, 10, 4), Q108 = c(7, 9, 1, 4, 1, 1, 10, 10, 5, 10,
10, 10, 1, 10, 10, 10, 10, 10, 1, 3), Q109 = c(6, 4, 1, 4, 1,
1, 1, 10, 10, 1, 6, 2, 10, 5, 10, 1, 10, 9, 1, 4), Q110 = c(6,
3, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 10, 1, 10, 3, 1, 3), Q112 =
c(8,
8, 10, 6, 10, 5, 10, 10, 10, 10, NA, 10, 10, 10, 10, 10, 10,
10, 10, 7), Q163 = c(6, 2, 10, 7, 9, 10, 10, 10, 10, NA, 10,
10, 6, 10, 3, NA, 8, 7, NA, 9), Q164 = c(4, 9, 10, 8, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10, 10, NA, 8, 10, 10, 10), Q222 = c(2,
1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 4, NA, 1, NA, 2, 3, NA, 3),
Q260 = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
1, 1, 0, 1), Q262 = c(33, 21, 60, 18, 60, 50, 45, 29, 62,
46, 35, 40, 30, NA, 45, NA, 30, 50, 36, 34), Q273 = c(1,
6, 1, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
Q275 = c(0, 2, 3, 3, 3, 2, 3, 2, 4, 0, 0, 0, 1, NA, 3, NA,
1, 1, 0, 1), Q281 = c(8, 0, 3, 0, 10, 3, 4, 6, 3, 8, 4, 4,
4, 0, 5, 0, 0, 0, 9, 0)), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -20L))
Here's a couple ideas using your sample data:
Use a dodged bar plot:
sample_data %>%
ggplot(aes(x = factor(Q1), fill = factor(Q49))) +
geom_bar(position = position_dodge(preserve = 'single')) +
labs(x = "Family Value",
y = "Count of Responses",
fill = "Life Satisfaction")
Use facets:
sample_data %>%
ggplot(aes(x = factor(Q49), fill = factor(Q49))) +
geom_bar() +
labs(x = "Life Satisfaction",
y = "Count of Responses",
fill = "Life Satisfaction") +
facet_wrap(vars(paste("Family Value", Q1)))
Use a heat map:
sample_data %>%
ggplot(aes(x = factor(Q1),y = factor(Q49))) +
geom_bin2d() +
coord_fixed() +
labs(y = "Life Satisfaction", x = "Family Value")

Is there a way, i can order the axis on a melted ggplot? [duplicate]

This question already has answers here:
Order discrete x scale by frequency/value
(7 answers)
How do you specifically order ggplot2 x axis instead of alphabetical order? [duplicate]
(2 answers)
ggplot2, Ordering y axis
(1 answer)
R ggplot ordering bars within groups
(1 answer)
Closed 6 months ago.
I have a Problem with a Plot I want to order, but it seems like it cant be.
install.packages("reshape2")
library(reshape2)
install.packages("ggplot2")
library(ggplot2)
df <- createRegressionTable(data,colname)
gg <- melt(df, id = "colname")
return(
ggplot(gg, aes(
x = colname, y = variable, fill = value
)) +
geom_tile(show.legend = FALSE) +
geom_text(aes(label = value), alpha = 0.6) +
scale_fill_gradient(low = "#D5E8D4", high = "#F8CECC") +
labs(
x = "Regressant",
y = "Regressor"
) +
theme(legend.key = element_blank())
)
I know the function createRegressionTable is a black box but this is the result:
list(colname = c("zielrichtungU", "zielrichtungO",
"imitationU", "imitationO", "steuerungU", "steuerungO", "neuheitU",
"neuheitO", "netzwerkU", "netzwerkO"), zielrichtungU = c(5, 1,
5, 1, 3, 4, 1, 1, 1, 1), zielrichtungO = c(1, 5, 1, 5, 1, 5,
3, 5, 1, 1), imitationU = c(5, 1, 5, 5, 1, 5, 1, 1, 4, 1), imitationO = c(1,
5, 5, 5, 1, 1, 5, 5, 5, 5), steuerungU = c(3, 1, 1, 1, 5, 5,
1, 2, 1, 1), steuerungO = c(4, 5, 5, 1, 5, 5, 3, 5, 1, 3), neuheitU = c(1,
3, 1, 5, 1, 3, 5, 5, 1, 1), neuheitO = c(1, 5, 1, 5, 2, 5, 5,
5, 1, 1), netzwerkU = c(1, 1, 4, 5, 1, 1, 1, 1, 5, 5), netzwerkO = c(1,
1, 1, 5, 1, 3, 1, 1, 5, 5))
I tested whether the output of melt is scrambled, but it seems to be ordered, as I wished, and now I don't know where the problem lies
And here is the Plot, that I'd love to order:

How to efficiently specify a large predictor matrix for stan data block

I would appreciate any help to create a large predictor matrix for stan data block.
I want to use variables w_1 to w_K from the data below as predictor "matrix" real<lower=0> weights[N, W]; in my model. K=W is the number of variables weights (columns of weights), N is the number of observation (rows of weights), so K and N are int.
my current approach below works for a few columns (e.g., K=10) but I have more, K>100 columns, therefore, given the data below, I need a function that provides an efficient and scalable way to do this:
#for the desired data block
dat1 <- list (N = N,
ncases = ncases, A = A, B = B, id = id, P = imput,
nn = nn, W = 10,
weights = cbind(w_1, w_2, w_3, w_4, w_5, w_6, w_7, w_8, w_9, w_10))
I explored compose_data from tidybayes but I fail to see how I could use that to accomplish what I want for desired data block. Therefore, Any help would be much appreciated.
#sample data
dat <- data.frame(
id = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4),
imput = c(1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5),
A = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
B = c(1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0),
Pass = c(278, 278, 278, 278, 278, 100, 100, 100, 100, 100, 153, 153, 153, 153, 153, 79, 79, 79, 79, 79),
Fail = c(740, 743, 742, 743, 740, 7581, 7581, 7581, 7581, 7581, 1231, 1232, 1235, 1235, 1232, 1731, 1732, 1731, 1731, 1731),
W_1= c(4, 3, 4, 3, 3, 1, 2, 1, 2, 1, 12, 12, 11, 12, 12, 3, 5, 3, 3, 3),
W_2= c(3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 12, 12, 12, 12, 12, 3, 3, 3, 3, 3),
W_3= c(4, 3, 3, 3, 3, 1, 2, 1, 1, 1, 12, 12, 11, 12, 12, 3, 3, 3, 3, 3),
W_4= c(3, 3, 4, 3, 3, 1, 1, 1, 2, 1, 12, 12, 13, 12, 12, 3, 2, 3, 3, 3),
W_5= c(3, 3, 3, 3, 3, 1, 0, 1, 1, 1, 12, 12, 12, 12, 12, 3, 3, 3, 3, 3),
W_6= c(4, 3, 3, 3, 3, 1, 1, 1, 1, 1, 12, 12, 12, 12, 12, 3, 3, 3, 3, 3),
W_7= c(3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 12, 12, 12, 12, 12, 3, 3, 3, 3, 3),
W_8= c(3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 15, 12, 12, 12, 12, 3, 3, 3, 3, 3),
W_9= c(3, 3, 3, 4, 3, 1, 1, 1, 1, 1, 12, 12, 12, 12, 12, 2, 3, 3, 3, 3),
W_10= c(3, 3, 4, 3, 3, 1, 1, 1, 1, 1, 12, 10, 12, 12, 12, 3, 3, 3, 3, 3)
)
#my current approach
N <- nrow(dat)
ncases <- dat$Pass
nn <- dat$Fail + dat$Pass
A <- dat$A
B <- dat$B
id <- dat$id
imput <- dat$imput
w_1 <- dat$W_1
w_2 <- dat$W_2
w_3 <- dat$W_3
w_4 <- dat$W_4
w_5 <- dat$W_5
w_6 <- dat$W_6
w_7 <- dat$W_7
w_8 <- dat$W_8
w_9 <- dat$W_9
w_10 <- dat$W_10
#for current data block
dat_list <-dat %>%compose_data(.n_name = n_prefix("N"))
#for desired data block
dat1 <- list (N = N,
ncases = ncases, A = A, B = B, id = id, P = imput, nn = nn, W = 10,
weights = cbind(w_1, w_2, w_3, w_4, w_5, w_6, w_7, w_8, w_9, w_10))
#current data block
data{
int N; // number of observations
int ncases[N];
int A[N];
int B[N];
int nn[N];
int id[N];
real<lower=0> w_1[N]; // variable w_1
real<lower=0> w_2[N]; // variable w_2
real<lower=0> w_3[N]; // variable w_3
real<lower=0> w_4[N]; // variable w_4
real<lower=0> w_5[N]; // variable w_5
real<lower=0> w_6[N]; // variable w_6
real<lower=0> w_7[N]; // variable w_7
real<lower=0> w_8[N]; // variable w_8
real<lower=0> w_9[N]; // variable w_9
real<lower=0> w_10[N]; // variable w_10
}
#desired data block
data{
int N; // number of observations
int ncases[N];
int A[N];
int B[N];
int nn[N];
int id[N];
real<lower=0> weights[N, W]; // N by W block of weights
}
This question has also been posted here. Thanks in advance for any help.
If all the predictor columns in dat start with W_, then I think this should do the trick:
w.matrix = as.matrix(dat[,grepl("^W_", colnames(dat))])
dat1 <- list (N = N, ncases = ncases, A = A, B = B, id = id, P = imput, nn = nn,
W = ncol(w.matrix), weights = w.matrix)

How to specify predictor matrix for stan data block?

Dear stackoverflow community. I want to use the variables w1 to w10 as predictor matrix matrix[N, W] weights; in my stan model. I am not certain how to accomplish that.
data frame
(dat <- data.frame(
id = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4),
imput = c(1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5),
A = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
B = c(1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0),
Pass = c(278, 278, 278, 278, 278, 100, 100, 100, 100, 100, 153, 153, 153, 153, 153, 79, 79, 79, 79, 79),
Fail = c(740, 743, 742, 743, 740, 7581, 7581, 7581, 7581, 7581, 1231, 1232, 1235, 1235, 1232, 1731, 1732, 1731, 1731, 1731),
W_1= c(4, 3, 4, 3, 3, 1, 2, 1, 2, 1, 12, 12, 11, 12, 12, 3, 5, 3, 3, 3),
W_2= c(3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 12, 12, 12, 12, 12, 3, 3, 3, 3, 3),
W_3= c(4, 3, 3, 3, 3, 1, 2, 1, 1, 1, 12, 12, 11, 12, 12, 3, 3, 3, 3, 3),
W_4= c(3, 3, 4, 3, 3, 1, 1, 1, 2, 1, 12, 12, 13, 12, 12, 3, 2, 3, 3, 3),
W_5= c(3, 3, 3, 3, 3, 1, 0, 1, 1, 1, 12, 12, 12, 12, 12, 3, 3, 3, 3, 3),
W_6= c(4, 3, 3, 3, 3, 1, 1, 1, 1, 1, 12, 12, 12, 12, 12, 3, 3, 3, 3, 3),
W_7= c(3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 12, 12, 12, 12, 12, 3, 3, 3, 3, 3),
W_8= c(3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 15, 12, 12, 12, 12, 3, 3, 3, 3, 3),
W_9= c(3, 3, 3, 4, 3, 1, 1, 1, 1, 1, 12, 12, 12, 12, 12, 2, 3, 3, 3, 3),
W_10= c(3, 3, 4, 3, 3, 1, 1, 1, 1, 1, 12, 10, 12, 12, 12, 3, 3, 3, 3, 3)
))
creating list
N <- nrow(dat)
ncases <- dat$Pass
nn <- dat$Fail + dat$Pass
A <- dat$A
B <- dat$B
id <- dat$id
imput <- dat$imput
w_1 <- dat$W_1
w_2 <- dat$W_2
w_3 <- dat$W_3
w_4 <- dat$W_4
w_5 <- dat$W_5
w_6 <- dat$W_6
w_7 <- dat$W_7
w_8 <- dat$W_8
w_9 <- dat$W_9
w_10 <- dat$W_10
dat1 <- list (N = N,
ncases = ncases, A = A, B = B, id = id, P = imput, nn = nn,
w1 = w_1, w2 = w_2, w3 = w_3, w4 = w_4, w5 = w_5,
w6 = w_6, w7 = w_7, w8 = w_8, w9 = w_9, w10 = w_10)
data block
data{
int N; // number of observations
int ncases[N]; // independent variable
int A[N]; // independent variable
int B[N]; // independent variable
int nn[N]; // independent variable
int id[N]; //individual id
int W[N]; //vector of weights
int P[N]; // number of imputations
matrix[N, W] weights; // design matrix of weights
}
Thank you in advance for any help.
If W in the data block is actually an int (rather than a vector; i.e., W is the number of columns in weights), then I would expect this to do what you need:
dat1 <- list (N = N,
ncases = ncases, A = A, B = B, id = id, P = imput, nn = nn, W = 10,
weights = cbind(w_1, w_2, w_3, w_4, w_5, w_6, w_7, w_8, w_9, w_10))

plot (ggplot ?) smooth + color area between 2 curves

I have a question for you please :
My data :
Nb_obs <- as.vector(c( 2, 0, 6, 2, 7, 1, 8, 0, 2, 1, 1, 3, 11, 5, 9, 6, 4, 0, 7, 9))
Nb_obst <- as.vector(c(31, 35, 35, 35, 39, 39, 39, 39, 39, 41, 41, 42, 43, 43, 45, 45, 47, 48, 51, 51))
inf20 <- as.vector(c(2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 4, 3, 5, 4))
sup20 <- as.vector(c(3, 4, 4, 4, 5, 4, 4, 5, 4, 4, 5, 5, 5, 6, 5, 6, 6, 5, 7, 6))
inf40 <- as.vector(c(1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 3, 3, 3, 4, 3))
sup40 <- as.vector(c(4, 5, 5, 5, 6, 5, 5, 6, 5, 5, 6, 6, 6, 7, 6, 7, 7, 7, 9, 7))
inf60 <- as.vector(c(1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 2))
sup60 <- as.vector(c(5, 6, 6, 6, 8, 7, 7, 7, 7, 7, 7, 7, 8, 9, 8, 9, 9, 9, 11, 9))
inf90 <- as.vector(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1))
sup90 <- as.vector(c(10, 11, 11, 11, 15, 13, 13, 14, 12, 13, 13, 13, 14, 17, 15, 17, 17, 16, 21, 18))
data <- cbind.data.frame(Nb_obs, Nb_obst, inf20, sup20, inf40, sup40, inf60 , sup60, inf90 , sup90)
My plot :
plot(data$Nb_obst, data$Nb_obs, type = "n", xlab = "Number obst", ylab = "number obs", ylim = c(0, 25))
lines(data$Nb_obst, data$inf20, col = "dark red")
lines(data$Nb_obst, data$sup20, col = "dark red")
lines(data$Nb_obst, data$inf40, col = "red")
lines(data$Nb_obst, data$sup40, col = "red")
lines(data$Nb_obst, data$inf60, col = "dark orange")
lines(data$Nb_obst, data$sup60, col = "dark orange")
lines(data$Nb_obst, data$inf90, col = "yellow")
lines(data$Nb_obst, data$sup90, col = "yellow")
My question :
There are two things I'd like to do (and so I think it could be done by ggplot):
In the idea of the graph at the top, the "inf" and "sup" are limits of my model in the IC 20%, then 40%, then 60%, and finally 90%. I would first like to smooth each curve, and then I would like to color the surface between two curves of the same IC, for example that the surface between "data$inf90" and "data$sup90" is yellow, the area between "data$inf60" and "data$60" is orange, etc. And I would like to superimpose each of these colored surfaces + put the good legend please.
Thanks for your help !
Cool question since I had to give myself a crash course in using LOESS for ribbons!
First thing I'm doing is getting the data into a long shape, since that's what ggplot will expect, and since your data has some characteristics that are kind of hidden within values. For example, if you gather into a long shape and have, say a column key, with a value of "inf20" and another of "sup20", those hold more information than you currently have access to, i.e. the measure type is either "inf" or "sup", and the level is 20. You can extract that information out of that column to get columns of measure types ("inf" or "sup") and levels (20, 40, 60, or 90), then map aesthetics onto those variables.
So here I'm getting the data into a long shape, then using spread to make columns of inf and sup, because those will become ymin and ymax for the ribbons. I made level a factor and reversed its levels, because I wanted to change the order of the ribbons being drawn such that the narrow one would come up last and be drawn on top.
library(tidyverse)
data_long <- data %>%
as_tibble() %>%
gather(key = key, value = value, -Nb_obs, -Nb_obst) %>%
mutate(measure = str_extract(key, "\\D+")) %>%
mutate(level = str_extract(key, "\\d+")) %>%
select(-key) %>%
group_by(level, measure) %>%
mutate(row = row_number()) %>%
spread(key = measure, value = value) %>%
ungroup() %>%
mutate(level = as.factor(level) %>% fct_rev())
head(data_long)
#> # A tibble: 6 x 6
#> Nb_obs Nb_obst level row inf sup
#> <dbl> <dbl> <fct> <int> <dbl> <dbl>
#> 1 0 35 20 2 2 4
#> 2 0 35 40 2 2 5
#> 3 0 35 60 2 1 6
#> 4 0 35 90 2 0 11
#> 5 0 39 20 8 3 5
#> 6 0 39 40 8 2 6
ggplot(data_long, aes(x = Nb_obst, ymin = inf, ymax = sup, fill = level)) +
geom_ribbon(alpha = 0.6) +
scale_fill_manual(values = c("20" = "darkred", "40" = "red",
"60" = "darkorange", "90" = "yellow")) +
theme_light()
But it still has the issue of being jagged, so for each level I predicted smoothed values of both inf and sup versus Nb_obst using loess. group_by and do yield a nested data frame, and unnest pulls it back out into a workable form. Feel free to adjust the span parameter, as well as other loess.control parameters that I know very little about.
data_smooth <- data_long %>%
group_by(level) %>%
do(Nb_obst = .$Nb_obst,
inf_smooth = predict(loess(.$inf ~ .$Nb_obst, span = 0.35), .$Nb_obst),
sup_smooth = predict(loess(.$sup ~ .$Nb_obst, span = 0.35), .$Nb_obst)) %>%
unnest()
head(data_smooth)
#> # A tibble: 6 x 4
#> level Nb_obst inf_smooth sup_smooth
#> <fct> <dbl> <dbl> <dbl>
#> 1 90 35 0 11.
#> 2 90 39 0 13.4
#> 3 90 48 0.526 16.7
#> 4 90 39 0 13.4
#> 5 90 41 0 13
#> 6 90 41 0 13
ggplot(data_smooth, aes(x = Nb_obst, ymin = inf_smooth, ymax = sup_smooth, fill = level)) +
geom_ribbon(alpha = 0.6) +
scale_fill_manual(values = c("20" = "darkred", "40" = "red",
"60" = "darkorange", "90" = "yellow")) +
theme_light()
Created on 2018-05-26 by the reprex package (v0.2.0).
This produces the plot with shaded areas using base R graphics.
The trick is to pair the x values with the y values.
plot(data$Nb_obst, data$Nb_obs, type = "n", xlab = "Number obst", ylab = "number obs", ylim = c(0, 25))
lines(data$Nb_obst, data$inf20, col = "dark red")
lines(data$Nb_obst, data$sup20, col = "dark red")
lines(data$Nb_obst, data$inf40, col = "red")
lines(data$Nb_obst, data$sup40, col = "red")
lines(data$Nb_obst, data$inf60, col = "dark orange")
lines(data$Nb_obst, data$sup60, col = "dark orange")
lines(data$Nb_obst, data$inf90, col = "yellow")
lines(data$Nb_obst, data$sup90, col = "yellow")
with(data, polygon(c(Nb_obst, rev(Nb_obst)), c(inf90, rev(sup90)), col = "yellow"))
with(data, polygon(c(Nb_obst, rev(Nb_obst)), c(inf60, rev(sup60)), col = "dark orange"))
with(data, polygon(c(Nb_obst, rev(Nb_obst)), c(inf40, rev(sup40)), col = "red"))
with(data, polygon(c(Nb_obst, rev(Nb_obst)), c(inf20, rev(sup20)), col = "dark red"))
The code for a ggplot graph is a bit longer. There is a function geom_ribbon perfect for this.
g <- ggplot(data)
g + geom_ribbon(aes(x = Nb_obst, ymin = sup60, ymax = sup90), fill = "yellow") +
geom_ribbon(aes(x = Nb_obst, ymin = sup40, ymax = sup60), fill = "dark orange") +
geom_ribbon(aes(x = Nb_obst, ymin = sup20, ymax = sup40), fill = "red") +
geom_ribbon(aes(x = Nb_obst, ymin = inf20, ymax = sup20), fill = "dark red") +
geom_ribbon(aes(x = Nb_obst, ymin = inf40, ymax = inf20), fill = "red") +
geom_ribbon(aes(x = Nb_obst, ymin = inf60, ymax = inf40), fill = "dark orange") +
geom_ribbon(aes(x = Nb_obst, ymin = inf90, ymax = inf60), fill = "yellow")
Data.
I will redo your dataset, simplifying its creation. You don't need as.vector and if you are creating a data.frame there is no need for the data.frame method of cbind, data.frame(.) is enough.
Nb_obs <- c( 2, 0, 6, 2, 7, 1, 8, 0, 2, 1, 1, 3, 11, 5, 9, 6, 4, 0, 7, 9)
Nb_obst <- c(31, 35, 35, 35, 39, 39, 39, 39, 39, 41, 41, 42, 43, 43, 45, 45, 47, 48, 51, 51)
inf20 <- c(2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 4, 3, 5, 4)
sup20 <- c(3, 4, 4, 4, 5, 4, 4, 5, 4, 4, 5, 5, 5, 6, 5, 6, 6, 5, 7, 6)
inf40 <- c(1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 3, 3, 3, 4, 3)
sup40 <- c(4, 5, 5, 5, 6, 5, 5, 6, 5, 5, 6, 6, 6, 7, 6, 7, 7, 7, 9, 7)
inf60 <- c(1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 2)
sup60 <- c(5, 6, 6, 6, 8, 7, 7, 7, 7, 7, 7, 7, 8, 9, 8, 9, 9, 9, 11, 9)
inf90 <- c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1)
sup90 <- c(10, 11, 11, 11, 15, 13, 13, 14, 12, 13, 13, 13, 14, 17, 15, 17, 17, 16, 21, 18)
data <- data.frame(Nb_obs, Nb_obst, inf20, sup20, inf40, sup40, inf60 , sup60, inf90 , sup90)

Resources