是否可以从R中获取CRAN包的发布日期?我想获得k个最近发布的CRAN包的列表,或者在日期dd-mm-yy之后发布的所有包。与available_packages_by_date.html上的信息类似?
available.packages()命令有一个“fields”参数,但这只从DESCRIPTION中提取字段。包描述上的日期字段并不总是最新的。
我可以使用来自html page的智能正则表达式来获取它,但我不确定这个html文件的可靠性和最新性......在某些时候,Kurt可能决定给出布局一个破坏剧本的改造。另一种方法是使用CRAN FTP中的时间戳,但我也不确定这个解决方案有多好。我不确定是否存在具有发布日期的正式结构文件?我假设HTML页面是从某个DB自动生成的。
答案 0 :(得分:5)
原来有一个未归档的文件“packages.rds”,其中包含所有包的发布日期(而不是时间)。我想这些数据每天都用于重新创建HTML文件。
在一个简单的函数下面,从这个文件中提取出版日期:
recent.packages.rds <- function(){
mytemp <- tempfile();
download.file("http://cran.r-project.org/web/packages/packages.rds", mytemp);
mydata <- as.data.frame(readRDS(mytemp), row.names=NA);
mydata$Published <- as.Date(mydata[["Published"]]);
#sort and get the fields you like:
mydata <- mydata[order(mydata$Published),c("Package", "Version", "Published")];
}
答案 1 :(得分:3)
最好的方法是利用包DESCRIPTION
发布在镜像镜像上的事实,并且由于DESCRIPTION
来自构建包,它包含有关何时打包的确切信息:
pkgs <- unname(available.packages()[, 1])[1:20]
desc_urls <- paste("http://cran.r-project.org/web/packages/", pkgs, "/DESCRIPTION", sep = "")
desc <- lapply(desc_urls, function(x) read.dcf(url(x)))
sapply(desc, function(x) x[, "Packaged"])
sapply(desc, function(x) x[, "Date/Publication"])
(我将其限制在前20个包中以说明基本想法)
答案 2 :(得分:2)
这是一个使用HTML和正则表达式的函数。我仍然宁愿从更正式的地方获取信息,以防HTML改变布局。
recent.packages <- function(number=10){
#html is malformed
maxlines <- number*2 + 11
mytemp <- tempfile()
if(getOption("repos") == "@CRAN@"){
repo <- "http://cran.r-project.org"
} else {
repo <- getOption("repos");
}
newurl <- paste(repo,"/web/packages/available_packages_by_date.html", sep="");
download.file(newurl, mytemp);
datastring <- readLines(mytemp, n=maxlines)[12:maxlines];
#we only find packages from after 2010-01-01
myexpr1 <- '201[0-9]-[0-9]{2}-[0-9]{2} </td> <td> <a href="../../web/packages/[a-zA-Z0-9\\.]{2,}/'
myexpr2 <- '^201[0-9]-[0-9]{2}-[0-9]{2}'
myexpr3 <- '[a-zA-Z0-9\\.]{2,}/$'
newpackages <- unlist(regmatches(datastring, gregexpr(myexpr1, datastring)));
newdates <- unlist(regmatches(newpackages, gregexpr(myexpr2, newpackages)));
newnames <- unlist(regmatches(newpackages, gregexpr(myexpr3, newpackages)));
newdates <- as.Date(newdates);
newnames <- substring(newnames, 1, nchar(newnames)-1);
returndata <- data.frame(name=newnames, date=newdates);
return(head(returndata, number));
}
答案 3 :(得分:1)
所以这是一个使用FTP中的目录列表的解决方案。这有点棘手,因为FTP以linux格式提供时间戳或一年的日期。除此之外它确实是它的工作。我仍然不相信这是可靠的。如果将包复制到另一个服务器,则可能会重置所有时间映射。
recent.packages.ftp <- function(){
setwd(tempdir())
download.file("ftp://cran.r-project.org/pub/R/src/contrib/", destfile=tempfile(), method="wget", extra="--no-htmlify");
#because of --no-htmlify the destfile argument does not work
datastring <- readLines(".listing");
unlink(".listing");
myexpr1 <- "(?<date>[A-Z][a-z]{2} [0-9]{2} [0-9]{2}:[0-9]{2}) (?<name>[a-zA-Z0-9\\.]{2,})_(?<version>[0-9\\.-]*).tar.gz$"
matches <- gregexpr(myexpr1, datastring, perl=TRUE);
packagelines <- as.logical(sapply(regmatches(datastring, matches), length));
#subset proper lines
matches <- matches[packagelines];
datastring <- datastring[packagelines];
N <- length(matches)
#from the ?regexpr manual
parse.one <- function(res, result) {
m <- do.call(rbind, lapply(seq_along(res), function(i) {
if(result[i] == -1) return("")
st <- attr(result, "capture.start")[i, ]
substring(res[i], st, st + attr(result, "capture.length")[i, ] - 1)
}))
colnames(m) <- attr(result, "capture.names")
m
}
#parse all records
mydf <- data.frame(date=rep(NA, N), name=rep(NA, N), version=rep(NA,N))
for(i in 1:N){
mydf[i,] <- parse.one(datastring[i], matches[[i]]);
}
row.names(mydf) <- NULL;
#convert dates
mydf$date <- strptime(mydf$date, format="%b %d %H:%M");
#So linux only displays dates for packages of less then six months old.
#However strptime will assume the current year for packages that don't have a timestamp
#Therefore for dates that are in the future, we subtract a year. We can use some margin for timezones.
infuture <- (mydf$date > Sys.time() + 31*24*60*60);
mydf$date[infuture] <- mydf$date[infuture] - 365*24*60*60;
#sort and return
mydf <- mydf[order(mydf$date),];
row.names(mydf) <- NULL;
return(mydf);
}
答案 4 :(得分:0)
您可以处理页面http://cran.r-project.org/src/contrib/
,并按空格分割字段,以获取完整指定的包源文件名,其中包括版本号和.gz后缀。
列表中还有一些其他项不是包文件,例如.rds文件,各种子目录等。
除非改变目录结构的呈现方式或文件的位置,否则我想不出比这更具权威性的内容。