Error in Ops.POSIXt ....

2,965 views
Skip to first unread message

Phil Taylor

unread,
Jan 23, 2014, 9:52:37 AM1/23/14
to ggp...@googlegroups.com
Hi everyone,

With the toy example below I get 

"Error in Ops.POSIXt((x - from[1]), diff(from)) : 
  '/' not defined for "POSIXt" objects"

It looks like this problem has been identified before:

and that a solution was apparently implemented. 

I'm all up-to-date with R (3.0.2) and ggplot2, but I still get the error.
Windows 7 Profession, 64 bit R 3.0.2

I want to be able to draw a single line ANYWHERE on a plot (e.g. between two facets) so if there is another solution, let me know.

Many thanks, 

Phil Taylor.

Toy example:

require(lubridate)
require(ggplot2)
tmp.df <- data.frame(x1 = seq(ymd("2010-03-02"), by = 1, length.out=20),
                     y1 = runif(20))

p <- ggplot(data=tmp.df, aes(x1,y1))
p <- p + geom_point() + 
  annotate("segment", 
           x = min(tmp.df$x),
           xend = max(tmp.df$x),
           y = -Inf, 
           yend = -Inf, 
           col="red") 
print(p)

Thomas

unread,
Jan 26, 2014, 12:23:55 PM1/26/14
to ggp...@googlegroups.com
There are two questions here. 1) Why is annotate still not working with dates and 2) Is it possible to draw a line between two facets.

1) The link you provided does suggest it has been fixed, but I can't get it to work with posixct dates either. The below solution is a cheap way of working around your problem. 

require(ggplot2)
tmp.df <- data.frame(x1 = seq(c(ISOdate(2010,03,02)), by = "day", length.out = 20), #note it captured the time change for daylight savings
                              y1 = runif(20),
                              fac=rep(c(0,1),10)) #create a variable for faceting

tmp.df$cheat<- as.numeric(julian(tmp.df$x1, origin=min(tmp.df$x1)))  #Convert to days julian counting up from the origin

p <- ggplot(data=tmp.df, aes(cheat,y1))+
geom_point()+  
  annotate("segment",   #controlling whether annotate appears in a facet or not has been covered elsewhere. 
          x =min(tmp.df$cheat),
          xend =max(tmp.df$cheat),
          y = 0, 
          yend = 19, 
          col="red")+
# relabel the x axis to convey dates, "breaks" gives the position and "labels" contains the text you want to display.
  scale_x_continuous(breaks=c(1,10,19), labels=tmp.df$x1[c(1,10,19)])+
#scale_x_continuous(breaks=c(1,10,19), labels=c("01-Mar", "07-Mar", "14-Mar"))+ 
#facet the plot. 
  facet_grid(fac~.)
print(p)

2) But you want the ability to draw a line between facets (connecting similar points in different subfigures to highlight a result or something like that).
I am not sure you can do this in ggplot with facet... however you can cheat and do this in base graphics (warning it is an ugly solution).

x11()
par(mfrow=c(2,1), xpd=NA) #setting XPD to NA allows you to plot across the entire device area...sort of.
plot(y1~x1, data=tmp.df[tmp.df$fac==1,])
plot(y1~x1, data=tmp.df[tmp.df$fac==0,])
lines(x=c(min(tmp.df$x1),max(tmp.df$x1)), y=c(0,3))

The problem with that solution is that the line created is relative to the plot it is created in. i.e. it doesn't scale to the area of the frame, it scales to the area of the panel; so you would have to play around with it to get a set of numbers that work at the figure size you want.

Dennis or Ista are likely to have better solutions / explanations.

Thomas  

Ista Zahn

unread,
Jan 27, 2014, 10:51:10 AM1/27/14
to Thomas, ggplot2
On Sun, Jan 26, 2014 at 12:23 PM, Thomas <thoma...@maine.edu> wrote:
> There are two questions here. 1) Why is annotate still not working with
> dates

Well, that is once question you can ask. Another is how can I add a
line to a plot with dates on one or more axis? The answer seems to be
"use aesthetic mapping rather then setting fixed values". To
illustrate:

require(lubridate)
require(ggplot2)
tmp.df <- data.frame(x1 = seq(ymd("2010-03-02"), by = 1, length.out=20),
y1 = runif(20),
fac=rep(c(0,1),10))

p <- ggplot(data=tmp.df, aes(x1,y1)) +
geom_point()

## annotate does not work:
p + annotate("segment",
x = min(tmp.df$x),
xend = max(tmp.df$x),
y = 0,
yend = Inf,
col="red")
## Error in Ops.POSIXt((x - from[1]), diff(from)) :
## '/' not defined for "POSIXt" objects

## geom_segment with fixed values does not work:
p + geom_segment(x = min(tmp.df$x),
xend = max(tmp.df$x),
y = 0,
yend = Inf,
col="red")
## Error in Ops.POSIXt((x - from[1]), diff(from)) :
## '/' not defined for "POSIXt" objects

## geom_segment with mapping does work. This is they way I recommend.
p + geom_segment(aes(xend = xend, yend = yend),
data = data.frame(
x1 = min(tmp.df$x1),
y1 = 0,
xend = max(tmp.df$x1),
yend = Inf),
color = "red")
## Works



and 2) Is it possible to draw a line between two facets.

Yes, it is, though as far as I know it will be very difficult to align
such a line with data points on the plot:

library(grid)
p + facet_wrap(~fac) +
annotation_custom(
grob = linesGrob(x = unit(c(0.1, 0.9), "npc"), y = unit(c(0.1, 0.9), "npc"))
)

grid.lines(x = unit(c(0, 1), "npc"), y = unit(c(.5, .8), "npc"), gp =
gpar(col = "red"))


HTH,
Ista
> --
> --
> You received this message because you are subscribed to the ggplot2 mailing
> list.
> Please provide a reproducible example:
> https://github.com/hadley/devtools/wiki/Reproducibility
>
> To post: email ggp...@googlegroups.com
> To unsubscribe: email ggplot2+u...@googlegroups.com
> More options: http://groups.google.com/group/ggplot2
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ggplot2" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to ggplot2+u...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
Reply all
Reply to author
Forward
0 new messages