y and x not the same length, scatterplot R - r

take the following as a simple example:
A <- c(1,1,1,2,2,3,3,4,4,4)
B <- c(1,0,0,1,0,1,0,1,0,0)
C <- c(6,3,2,4,1,2,6,8,4,3)
data <- data.frame(A,B,C)
data
I want to create a scatterplot that looks like so:
without the blue and red boarders, they are there as an explanitary guide
So I want to plot:
Each time B=1, I want to use its C value for the horizontal scale and plot the C value where B=0 along the vertical scale.
So for example; where X=6, we have points at x=3 and 2
where X=4, we have points at x=1
where X=2, we have a point at x=6
where X=8, we have a points at x=4 and 3
Must i manipuulate/melt/reshape my data somehow?

Using na.locf from the zoo package there is no need for reshaping.
library(zoo)
#extract the part of C that we need for mapping x
data$D = ifelse(data$B==1,data$C,NA)
#fill in the blanks
data$D = na.locf(data$D)
#Extract from C what we need for y
data$E = ifelse(data$B==1,NA,data$C)
#Done!
plot(data$D,data$E)

Related

ggplot with points and plots of certain columns

Let's say I have a data.frame of three columns:
x <- seq(1,10)
y <- 0.1*x^2
z <- y+rnorm(10,0,10)
d <- data.frame(x,y,z)
I now want a ggplot that plots the points (x,z) and somewhat smooth lines going through (x,y).
How can I achieve that?
"%>%" <- magrittr::"%>%"
d %>%
ggplot2::ggplot(ggplot2::aes(x=x)) +
ggplot2::geom_point(ggplot2::aes(y=z)) +
ggplot2::geom_smooth(ggplot2::aes(y=y))

Draw 3d contours on scatterplot

I have a dataset where each row corresponds to an x,y and z value.
I would like to create a 2d scatterplot of variables x and y and overlay the 2d contours of the 3 dimensional space.
I tried the following:
load("https://www.dropbox.com/s/ya5g2n47al2cn1j/df.Rdata?dl=0")
df <- as.data.frame(df)
ggplot(data=df, aes(x=df$x,y=df$y,color=df$z))+
geom_point()+
geom_contour(aes(z=df$z))
but I get the warning message:
Warning message:
Not possible to generate contour data
Is there a way to do this? Most examples I could find online use similar data of x, y, z form
Here's how the data looks:
> head(df)
x y z
1 0.15395671 0.1548728 -9.622222e-02
2 0.18148413 0.1554308 -1.091111e-01
3 0.07870902 0.1538021 -2.911111e-02
4 0.13514970 0.1134729 -1.133333e-01
5 0.03504008 0.1053258 4.222222e-03
6 0.02161680 0.1140364 -1.110223e-16
I think your data may not have a value of z for each possible combination of x and y values; you could not have a matrix that is "x" rows and "y columns and have a value of z at each index, you would have gaps. You may still be able to get what you want with geom_density_2d(), however. Given your example data above:
x<-c(0.15395671, 0.18148413, 0.07870902, 0.1351497, 0.03504008, 0.0216168)
y<-c(0.1548728, 0.1554308, 0.1538021, 0.1134729, 0.1053258, 0.1140364)
z<-c(-0.09622222, -0.1091111, -0.02911111, -0.1133333, 0.004222222, 0)
xyz <- data.frame(x,y,z)
ggplot(xyz, aes(x, y, z = z) ) + geom_density_2d()

Give color to scatter plot points based on value thershold

I have data.frame of value between -10 to 10, my data.frame has 2 columns.I wanted to create a ggplot graph.
I need to give color to points which have values more than 8 or less than -8.
How can I do this by ggplot in geom_point()?
I agree with the comments above, anyway I think this is what you are looking for
p <- runif(100, min=-10, max=10)
g <- 1:100
dat <- data.frame(p, g)
dat$colors <- 1
dat[which(dat$p < (-8) | dat$p > 8),"colors"] <- 0
library(ggplot2)
ggplot(dat, aes(x=g, y=p, group=colors)) + geom_point(aes(color=as.factor(colors)))
Which results in this:
Edit:
In a previous version of this answer the different colors were expressed as a continuous variable. I changed this to a dichotomous format with as.factor.

Creating a colour gradient around zero in filled.contour

I am new to R and am struggling to find an answer to what I thought would be a relatively common question. I am creating a world map of a variable using filled.contour. For example:
z=matrix(rnorm(7008),nrow=96)
x=seq(-176.25,180, by=3.75)
y=seq(-90,90, by=2.5)
filled.contour(x,y,z, plot.axes={axis(1); axis(2); map(add=TRUE, interior=FALSE)} )
In which x & y are longitude and latitude, and z is a data matrix. I have spent time applying my own colours and levels, however I want to have a gradient of colour with white assigned as zero. With negative number grading to dark blue and positive to dark red through green and yellow.
I have tried to use the color.scale function from the 'plotrix' package
cellcol=matrix(rep("#000000",7008),nrow=96) # replicating the size of my matrix z
cellcol[z>0]=color.scale(z[z>0], c(0,1,1),c(1,1,0),0) # values above zero grading to red
cellcol[z<0]=color.scale(z[z<0], 0, 0,c(0,1)) # values below zero grading to blue
However now I am stuck. Is this the best way to go about doing this? If so how do I input this into the the filled.contour code above? I'm sure it is simple yet can't get it to work.
Thanks for any help in advance.
I have only managed to achieve what you want using ggplot2.
You can try the following (I submerged the volcano data as an example):
library(ggplot2)
library(reshape2)
## Just an example, I subtract the mean to have positive and negative values for z
dd <- volcano-mean(volcano)
## Creates a data.frame with columns x, y, z
dd <- melt(dd)
names(dd) <- c('x','y','z')
## Does the contour plot
d <- ggplot(dd, aes(x,y,z=z))
d + geom_tile(aes(fill=z)) + scale_fill_gradient2(low="blue", high="red")
I wrote a small function that does what you want to achieve:
myFilled.contour <- function(x = seq(0, 1, length.out = nrow(z)),
y = seq(0, 1, length.out = ncol(z)),
z, nlevels=30, ...) {
ma <- max(abs(z))
lvls <- seq(-ma, ma, length.out = nlevels)
cols <- colorRampPalette(c("blue","white","red")) (nlevels - 1)
filled.contour(x, y, z, plot.axes={axis(1); axis(2)},
col=cols, levels=lvls, ...)
}
Using filled.contour and again the submerged volcano dd:
myFilled.contour(z=d)
Using your data:
myFilled.contour(x,y,z)
Caveat: The legend includes levels not used in the contour plot.
Hope it helps,
alex

Connecting Lines from One Group, Colors from Another Group

I have data conditioned on two variables, one major condition, one minor condition. I want a xyplot (lattice) with points and lines (type='b'), in one panel so that the major condition determines the color and the minor condition is used for drawing the lines.
Here is an example that is representative of my problem (see the code below to produce the data frame). d is the major condition, and c is the minor condition.
> dat
x y c d
1 1 0.9645269 a A
2 2 1.4892217 a A
3 3 1.4848654 a A
....
10 10 2.4802803 a A
11 1 1.5606218 b A
12 2 1.5346806 b A
....
98 8 2.0381943 j B
99 9 2.0826099 j B
100 10 2.2799917 j B
The way to get the connecting lines to be conditioned on c is to use groups=c in the plot. Then the way to tell them apart is to use a formula conditioned on d:
xyplot(y~x|d, data=dat, type='b', groups=c)
However, I want the plots in the same panel. Removing the formula condition on d produces one panel, but when group=d is specified, there are "retrace" lines drawn:
xyplot(y~x, data=dat, type='b', groups=d, auto.key=list(space='inside'))
What I want looks very like the above plot, only without these "retrace" lines.
It's possible to set the colors explicitly in this example, as I know that there are five lines of category 'A' followed by five of category 'B', but this won't easily work for my real problem. In addition, auto.key is useless when setting the colors this way:
xyplot(y~x, data=dat, type='b', groups=c, col=rep(5:6, each=5))
The data:
set.seed(1)
dat <- do.call(
rbind,
lapply(1:10,
function(x) {
firsthalf <- x < 6
data.frame(x=1:10, y=log(1:10 + rnorm(10, .25) + 2 * firsthalf),
c=letters[x],
d=LETTERS[2-firsthalf]
)
}
)
)
The default graphical parameters are obtained from the superpose.symbol and superpose.line. One solution s to set them using par.settings argument.
## I compute the color by group
col <-by(dat,dat$c,
FUN=function(x){
v <- ifelse(x$d=='A','darkgreen','orange')
v[1] ## I return one parameter , since I need one color
}
)
xyplot(y~x, data=dat, type='b', groups=c,
auto.key = list(text =levels(dat$d),points=F),
par.settings=
list(superpose.line = list(col = col), ## color of lines
superpose.symbol = list(col=col), ## colors of points
add.text = list(col=c('darkgreen','orange')))) ## color of text in the legend
Does it have to be lattice? In ggplot it is rather easy:
library(ggplot2)
ggplot(dat, aes(x=x,y=y,colour=d)) + geom_line(aes(group=c),size=0.8) + geom_point(shape=1)
This is a quick and dirty example. You can customize the colour of the lines, the legend , the axis, the background,...

Resources