[R-sig-eco] order of id's in ltraj object
Clement Calenge
clement.calenge at oncfs.gouv.fr
Wed Mar 13 10:56:53 CET 2013
On 03/09/2013 12:55 AM, Sebastian P. Luque wrote:
> Hi,
>
> I noticed that as.ltraj() reorders the id's alphanumerically. However,
> I'd like to keep the order in the input data.frame or
> SpatialPointsDataFrame for plotting purposes. Is there some way to
> achieve that, except for manipulating the structure of the ltraj object?
There is currently no way to do it, except for manipulating the
structure of the ltraj object. However, I will submit a new version of
the package in which the function as.ltraj does not reorder the id's or
the burst automatically. It will be available on CRAN in a few days.
Meanwhile, you can use the following function:
as.ltraj <- function(xy, date=NULL, id, burst=id, typeII = TRUE,
slsp = c("remove", "missing"),
infolocs = data.frame(pkey = paste(id, date,
sep=".")))
{
## Various verifications
if (typeII) {
if (!inherits(date,"POSIXct"))
stop("For objects of type II,\n date should be of class
\"POSIXct\"")
} else {
date <- 1:nrow(xy)
}
if (length(date) != nrow(xy))
stop("date should be of the same length as xy")
slsp <- match.arg(slsp)
## Length of infolocs, if provided
if (!is.null(infolocs)) {
if (nrow(infolocs)!=nrow(xy))
stop("infolocs should have the same number of rows as xy")
}
## length of id
if (length(id)==1)
id <- factor(rep(as.character(id), nrow(xy)))
if (length(id)!=nrow(xy))
stop("id should be of the same length as xy, or of length 1")
## checks that all levels are present in the data:
if (min(table(id))==0)
stop("some id's are not present in the data")
## length of burst
if (length(burst)==1)
burst <- factor(rep(as.character(burst), nrow(xy)))
if (length(burst)!=nrow(xy))
stop("burst should be of the same length as xy, or of length 1")
## checks that all levels are present in the data:
if (min(table(burst))==0)
stop("some bursts are not present in the data")
## Verification that there is only one burst per id
id1 <- factor(id)
burst1 <- factor(burst)
if (!all(apply(table(id1,burst1)>0,2,sum)==1))
stop("one burst level should belong to only one id level")
x <- xy[,1]
y <- xy[,2]
res <- split(data.frame(x=x,y=y, date=date), burst)
liid <- split(id, burst)
if (!is.null(infolocs))
linfol <- split(infolocs, burst)
## sort the dates
if (!is.null(infolocs))
linfol <- lapply(1:length(linfol),
function(j)
linfol[[j]][order(res[[j]]$date),,drop=FALSE])
res <- lapply(res, function(y) y[order(y$date),,drop=FALSE])
## Unique dates?
rr <- any(unlist(lapply(res,
function(x)
(length(unique(x$date))!=length(x$date)))))
if (rr)
stop("non unique dates for a given burst")
## Unique dates for a given id?
x <- xy[,1]
y <- xy[,2]
resbb <- split(data.frame(x=x,y=y, date=date), id1)
rr <- any(unlist(lapply(resbb,
function(x)
(length(unique(x$date))!=length(x$date)))))
if (rr)
stop("non unique dates for a given id")
## Descriptive parameters
foo <- function(x) {
x1 <- x[-1, ]
x2 <- x[-nrow(x), ]
dist <- c(sqrt((x1$x - x2$x)^2 + (x1$y - x2$y)^2),NA)
R2n <- (x$x - x$x[1])^2 + (x$y - x$y[1])^2
dt <- c(unclass(x1$date) - unclass(x2$date), NA)
dx <- c(x1$x - x2$x, NA)
dy <- c(x1$y - x2$y, NA)
abs.angle <- ifelse(dist<1e-07,NA,atan2(dy,dx))
## absolute angle = NA if dx==dy==0
so <- cbind.data.frame(dx=dx, dy=dy, dist=dist,
dt=dt, R2n=R2n, abs.angle=abs.angle)
return(so)
}
speed <- lapply(res, foo)
res <- lapply(1:length(res), function(i) cbind(res[[i]],speed[[i]]))
## The relative angle
ang.rel <- function(df,slspi=slsp) {
ang1 <- df$abs.angle[-nrow(df)] # angle i-1
ang2 <- df$abs.angle[-1] # angle i
if(slspi=="remove"){
dist <- c(sqrt((df[-nrow(df),"x"] - df[-1,"x"])^2 +
(df[-nrow(df),"y"] - df[-1,"y"])^2),NA)
wh.na <- which(dist<1e-7)
if(length(wh.na)>0){
no.na <- (1:length(ang1))[!(1:length(ang1)) %in% wh.na]
for (i in wh.na){
indx <- no.na[no.na<i]
ang1[i] <- ifelse(length(indx)==0,NA,ang1[max(indx)])
}
}
}
res <- ang2-ang1
res <- ifelse(res <= (-pi), 2*pi+res,res)
res <- ifelse(res > pi, res -2*pi,res)
return(c(NA,res))
}
## Output
rel.angle <- lapply(res, ang.rel)
res <- lapply(1:length(res),
function(i) data.frame(res[[i]],
rel.angle=rel.angle[[i]]))
res <- lapply(1:length(res), function(i) {
x <- res[[i]]
attr(x, "id") <- as.character(liid[[i]][1])
attr(x,"burst") <- levels(factor(burst))[i]
return(x)
})
## And possibly, the data.frame infolocs
if (!is.null(infolocs)) {
res <- lapply(1:length(res), function(i) {
x <- res[[i]]
y <- linfol[[i]]
row.names(y) <- row.names(x)
attr(x, "infolocs") <- y
return(x)
})
}
## Output
class(res) <- c("ltraj","list")
attr(res,"typeII") <- typeII
attr(res,"regular") <- is.regular(res)
return(res)
}
Best,
Clément Calenge
--
Clément CALENGE
Cellule d'appui à l'analyse de données
Direction des Etudes et de la Recherche
Office national de la chasse et de la faune sauvage
Saint Benoist - 78610 Auffargis
tel. (33) 01.30.46.54.14
More information about the R-sig-ecology
mailing list