8

R内からCRANパッケージの発行日を取得することは可能ですか? 最近公開された k 個の CRAN パッケージ、または日付 dd-mm-yy 以降に公開されたすべてのパッケージのリストを取得したいと考えています。available_packages_by_date.htmlの情報に似ていますか?

available.packages() コマンドには「フィールド」引数がありますが、これは説明からフィールドを抽出するだけです。パッケージの説明の日付フィールドは、常に最新であるとは限りません。

HTMLページからスマートな正規表現を使用して取得できますが、このHTMLファイルがどれほど信頼性が高く最新のものであるかはわかりません...ある時点で、Kurtはレイアウトを変更してレイアウトを壊すことを決定するかもしれません脚本。別の方法として、 CRAN FTPのタイムスタンプを使用することもできますが、このソリューションがどれほど優れているかはわかりません。正式に構造化された、発行日が記載されたファイルがどこかにあるかどうかわかりませんか? HTML ページは何らかの DB から自動的に生成されると想定しています。

4

5 に答える 5

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")];
}
于 2012-01-12T05:13:43.530 に答える
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 個のパッケージに制限しています)

于 2012-01-05T21:09:12.130 に答える
2

Here a function that uses the HTML and regular expressions. I still rather get the information from a more formal place though in case the HTML ever changes layout.

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));
}
于 2012-01-04T06:20:01.810 に答える
1

ここでは、FTP からの dir リストを使用するソリューションを示します。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);
}
于 2012-01-04T23:55:48.390 に答える
0

ページを処理しhttp://cran.r-project.org/src/contrib/、フィールドを空白で分割して、バージョン # と .gz サフィックスを含む完全に指定されたパッケージ ソース ファイル名を取得できます。

リストには、.rds ファイル、さまざまなサブディレクトリなど、パッケージ ファイルではない項目がいくつかあります。

ディレクトリ構造の表示方法やファイルの場所の変更を除いて、これよりも信頼できるものは考えられません。

于 2012-01-04T23:26:23.303 に答える