Aesthetics must either be length one or the same length - r

I am trying to plot values and errorbars, a seemingly simple task. As the script is fairly long, I am trying to limit the code in give here to the necessary amount.
I can plot the graph without error bars. However, when trying to add the errorbars I get the message
Error: Aesthetics must either be length one, or the same length as the dataProblems:Tempdata
This is the code I am using. All vectors in the Tempdata data frame are of length 390.
Tempdata <- data.frame (TempDiff, Measurement.points, Room.ext.resc, MelatoninData, Proximal.vs.Distal.SD.ext, ymax, ymin)
p <- ggplot(data=Tempdata,
aes(x = Measurement.points,
y = Tempdata, colour = "Temperature Differences"))
p + geom_line(aes(x=Measurement.points, y = Tempdata$TempDiff, colour = "Gradient Proximal vs. Distal"))+
geom_errorbar(aes(ymax=Tempdata$ymax, ymin=Tempdata$ymin))

The problem is that you have the colour-variables between quotation marks. You should put the variable name at that spot. So, replacing "Temperature Differences" with TempDiff and "Gradient Proximal vs. Distal" with Proximal.vs.Distal.SD.ext will probably solve your problem.
Furthermore: you can can't call for two different colour-variables.
The improved ggplot code should probably be something like this:
ggplot(data=Tempdata, aes(x=Measurement.points, y=TempDiff, colour=Proximal.vs.Distal.SD.ext)) +
geom_line() +
geom_errorbar(aes(ymax=ymax, ymin=ymin))
I also fixed some more problems with your original code:
the $ issue reported by Roland
the fact that you have conflicting calls in your aes
the fact you are calling your dataframe inside the first aes

Related

geom_boxplot not displaying correctly

In the assignment I am doing, it wants me to use geom_boxplot. However, I have been unable to get the graph to display the boxplots correctly.
# Convert To Factor
census_data$CIT <- as.factor(census_data$CIT)
class(census_data$CIT)
ggplot(census_data, aes(census_data[["VALP"]], (census_data[["CIT"]])) +
geom_boxplot(color = "blue", fill = "orange") +
ggtitle("Property value by citizenship status") +
xlab("“Citizenship status") + ylab("Property value")
I am slightly concerned that the CIT may not have been converted correctly to a factor.
I think you have your x and y aesthetics the wrong way around. you have VALP first which is then assumed to be x and CIT second which is asssumed to be y. Given your labels I think you want them in the other order.
I always find it helps to label them explicitly, ie aes(x=.., y=...) so you don't get confused!
You also don't need to use census_data[["VALP"]] in the aes function call, since you have supplied the census_data in the data argument just saying aes(x=CIT, y=VALP) should be enough.

ggplot stat_density with facet_wrap and single stat_density doesn't match [duplicate]

When using facet_grid(x ~ y) with ggplot2 I've seen in various examples and read in the documentation that the x variable is laid out vertically and the y variable horizontally. However, when I run the following:
set.seed(1)
b = c(rnorm(10000,mean=0,sd=0.5),rnorm(10000,mean=5,sd=0.5),
rnorm(10000,mean=7,sd=0.5),rnorm(10000,mean=10,sd=0.5))
x = c(rep('xL', 20000), rep('xR',20000))
y = c(rep('yL',10000), rep('yR',20000), rep('yL',10000))
foo = data.frame(x=x,y=y,b=b)
ggplot(data=foo, aes(foo$b)) +
geom_histogram(aes(y=..density..),breaks=seq(-5,12,by=.2),col='steelblue',fill='steelblue2') +
geom_density(col='black') +
facet_grid(x ~ y, scales='free_y')
I get the below (sorry for the quality). And even though, from above, the distribution with mean 10 is the one with (x,y) of 'xR,xL' that one appears in the bottom right quadrant which has labels 'xR,yR'. What am I doing wrong?
Change aes(foo$b) to aes(x = b) to make sure the aesthetics are mapping correctly.
You want to make sure ggplot is finding the column labelled b from the correct scope i.e. from the data that it has been passed. For example, it may be the case that ggplot rearranged your data when you passed it, so mapping the variable foo$b no longer aligns with what you want.
I'm not saying this is what happened - just an example of why calling the aesthetic from the correct scope is important.

addressing `data` in `geom_line` of ggplot

I am building a barplot with a line connecting two bars in order to show that asterisk refers to the difference between them:
Most of the plot is built correctly with the following code:
mytbl <- data.frame(
"var" =c("test", "control"),
"mean1" =c(0.019, 0.022),
"sderr"= c(0.001, 0.002)
);
mytbl$var <- relevel(mytbl$var, "test"); # without this will be sorted alphabetically (i.e. 'control', then 'test')
p <-
ggplot(mytbl, aes(x=var, y=mean1)) +
geom_bar(position=position_dodge(), stat="identity") +
geom_errorbar(aes(ymin=mean1-sderr, ymax=mean1+sderr), width=.2)+
scale_y_continuous(labels=percent, expand=c(0,0), limits=c(NA, 1.3*max(mytbl$mean1+mytbl$sderr))) +
geom_text(mapping=aes(x=1.5, y= max(mean1+sderr)+0.005), label='*', size=10)
p
The only thing missing is the line itself. In my very old code, it was supposedly working with the following:
p +
geom_line(
mapping=aes(x=c(1,1,2,2),
y=c(mean1[1]+sderr[1]+0.001,
max(mean1+sderr) +0.004,
max(mean1+sderr) +0.004,
mean1[2]+sderr[2]+0.001)
)
)
But when I run this code now, I get an error: Error: Aesthetics must be either length 1 or the same as the data (2): x, y. By trying different things, I came to an awkward workaround: I add data=rbind(mytbl,mytbl), before mapping but I don't understand what really happens here.
P.S. additional little question (I know, I should ask in a separate SO post, sorry for that) - why in scale_y_continuous(..., limits()) I can't address data by columns and have to call mytbl$ explicitly?
Just put all that in a separate data frame:
line_data <- data.frame(x=c(1,1,2,2),
y=with(mytbl,c(mean1[1]+sderr[1]+0.001,
max(mean1+sderr) +0.004,
max(mean1+sderr) +0.004,
mean1[2]+sderr[2]+0.001)))
p + geom_line(data = line_data,aes(x = x,y = y))
In general, you should avoid using things like [ and $ when you map aesthetics inside of aes(). The intended way to use ggplot2 is usually to adjust your data into a format such that each column is exactly what you want plotted already.
You can't reference variables in mytbl in the scale_* functions because that data environment isn't passed along like it is with layers. The scales are treated separately than the data layers, and so the information about them is generally assumed to live somewhere separate from the data you are plotting.

Why is facet_grid placing the distributions in the wrong quadrants?

When using facet_grid(x ~ y) with ggplot2 I've seen in various examples and read in the documentation that the x variable is laid out vertically and the y variable horizontally. However, when I run the following:
set.seed(1)
b = c(rnorm(10000,mean=0,sd=0.5),rnorm(10000,mean=5,sd=0.5),
rnorm(10000,mean=7,sd=0.5),rnorm(10000,mean=10,sd=0.5))
x = c(rep('xL', 20000), rep('xR',20000))
y = c(rep('yL',10000), rep('yR',20000), rep('yL',10000))
foo = data.frame(x=x,y=y,b=b)
ggplot(data=foo, aes(foo$b)) +
geom_histogram(aes(y=..density..),breaks=seq(-5,12,by=.2),col='steelblue',fill='steelblue2') +
geom_density(col='black') +
facet_grid(x ~ y, scales='free_y')
I get the below (sorry for the quality). And even though, from above, the distribution with mean 10 is the one with (x,y) of 'xR,xL' that one appears in the bottom right quadrant which has labels 'xR,yR'. What am I doing wrong?
Change aes(foo$b) to aes(x = b) to make sure the aesthetics are mapping correctly.
You want to make sure ggplot is finding the column labelled b from the correct scope i.e. from the data that it has been passed. For example, it may be the case that ggplot rearranged your data when you passed it, so mapping the variable foo$b no longer aligns with what you want.
I'm not saying this is what happened - just an example of why calling the aesthetic from the correct scope is important.

How can I plot the relative proportions of two groups using a fill aesthetic in ggplot2?

How can I plot the relative proportions of two groups using a fill aesthetic in ggplot2?
I am asking this question here because several other answers on this topic seem incorrect (ex1, ex2, and ex3), but Cross Validated seems to have functionally banned R specific questions (CV meta). ..density.. is conceptually related to, but distinct from proportions (ex4 and ex5). So the correct answer does not seem to involve density.
Example:
set.seed(1200)
test <- data.frame(
test1 = factor(sample(letters[1:2], 100, replace = TRUE,prob=c(.25,.75)),ordered=TRUE,levels=letters[1:2]),
test2 = factor(sample(letters[3:8], 100, replace = TRUE),ordered=TRUE,levels=letters[3:8])
)
ggplot(test, aes(test2)) + geom_bar(aes(y = ..density.., group=test1, fill=test1) ,position="dodge")
#For example, the plotted data shows level a x c as being slightly in excess of .15, but a manual calculation shows a value of .138
counts <- with(test,table(test1,test2))
counts/matrix(rowSums(counts),nrow=2,ncol=6)
The answer that seems to yield an output that is correct resorts to a solution that doesn't use ggplot2 (calculating it outside of ggplot2) or requires that a panel be used rather than a fill aesthetic.
Edit: Digging into stat_bin yields that the function ultimately called is bin, but bin only gets passed the values in the x aes. Without rewriting stat_bin (or making another stat_) the hack that was applied in the above referenced answer can be generalized to the fill aes in the absence of the group aes with the following code for the y aes: y = ..count../sapply(fill, FUN=function(x) sum(count[fill == x])). This just replaces PANEL (the hidden column that is present at the end of StatBin) with fill). Presumably other hidden variables could get the same treatment.
This is an aweful hack, but it seems to do what you want...
ggplot(test, aes(test2)) + geom_bar(aes(y = ..count../rep(c(sum(..count..[1:6]), sum(..count..[7:12])), each=6),
group=test1, fill=test1) ,position="dodge") +
scale_y_continuous(name="proportion")

Categories

Resources