2016-07-31 21 views
5

Paket geliştiriciyim ve paketimi DESCRIPTION dosyasında kullanmak için gereken en düşük R sürümünü belirtmek istiyorum.Tüm paket bağımlılıkları için minimum R sürümünü belirleyin

available.packages paketlerin TANIMLARINI ayrıştırıyor, ancak sonuç (kolayca) Makinenin okunabilir bağımlılıkları aramak için kolayca okunabilir değil, çünkü Alış ve Gönderme alanları virgülle ayrılmış metin olduğundan ve bazen paketlerin sürüm gereksinimlerine sahip olduklarından.

Listing R Package Dependencies Without Installing Packages'da açıklanan çözüm, özyinelemeli bir çözüm değildir. Yuvalanmış bir bağımlılık R> 3.3 'e ihtiyaç duyuyorsa, bunu bilmek istiyorum.

En azından, belirli bir CRAN paketi için R'nin en düşük ve içe aktarılan, bağlı ve bağımlı paketlerini görmek istiyorum. En azından R veya paket versiyonunu belirleyen paketi veya paketleri listelemek daha iyi olacaktır.

Daha yüksek sürüm gereksinimlerine sahip olan bağımlılıkları ortadan kaldırarak, düzeltemedikleri kurumsal eski R sürümleriyle daha fazla kişiye hizmet verebilirim: bazıları hala R 2.x.

+0

, ama bir yöntem olabilir ilk olarak R sürümlerinin tarihlerini kontrol etmek ve daha sonra herhangi bir paketi sonraki tarihlere yüklememek. (Bir R betiği olmayacaktır.) R'nin ve belirli işletim sisteminin belirli bir sürümü için uygun bir dizi oluşturma aracının bulunduğundan emin olmanız gerekir, çünkü kapsamlı bir ikili paket deposu yoktur. Bir alternatif, kullanım R'lerinin geriye dönük nedenlerini belirlemek ve bu sorunları düzeltmek olabilir. –

+1

Ve söz konusu soruya verilen ikinci cevap, özyinelemeli bir çözüm önerdi. Yani belki bu bir kopyasıdır (onaylanmış çözüm tamamen tatmin edici olsa bile)? Yinelenen olarak işaretlemeyi tutacağım ancak soru, gereksinimlerin daha eksiksiz bir tanımını içerecek şekilde düzenlenmediği sürece bunu yapabilir. –

+1

Ne yazık ki, bu potansiyel tehlike ile doludur. ['Rodham'] gibi bir paketiniz var (https://cran.rstudio.com/web/packages/rodham/) _claim_> = 2.1.0, ancak _actually_ need> = 3.2.0; 3.2.0'da tanıtılan ve 2.1.0'da bulunmayan işlev ('trimws()'). 3.2.0'dan sonra CRAN'a girildiğinden ve CRAN testleri sadece mevcut ve devel sürümleriyle sunulduğundan, bu bağımlılık hatasını kaçıracaktır. Her bir R sürümü ile bir dizi docker görüntüsü oluşturmanın ve pkg testlerini min sürümlerini belirlemek için onlara karşı çalıştırmanın daha iyi olacağından şüpheleniyorum. Çok otomatikleştirilebilir. – hrbrmstr

cevap

4
min_r_version <- function(package="ggplot2", exclude_main_pkg=TRUE) { 

    purrr::walk(c("tools", "purrr", "devtools", "stringi", "tidyr", "dplyr"), 
       require, character.only=TRUE) 

    deps <- package_dependencies(package, recursive=TRUE) 

    if (exclude_main_pkg) { 
    pkgs <- deps[[1]] 
    } else { 
    pkgs <- c(package, deps[[1]]) 
    } 

    available.packages() %>% 
    as_data_frame() %>% 
    filter(Package %in% pkgs) %>% 
    select(Depends) %>% 
    unlist() -> pkg_list 

    # if main pkg only relied on core R packages (i.e. pkgs that aren't in CRAN) and we 
    # excluded the pkg itself from the min version calculation, this is an edge case we need 
    # to handle. 

    if (length(pkg_list) == 0) return("Unspecified") 

    stri_split_regex(pkg_list, "[,]") %>% 
    unlist() %>% 
    trimws() %>% 
    stri_match_all_regex(c("^R$|^R \\(.*\\)$")) %>% 
    unlist() %>% 
    discard(is.na(.)) %>% 
    unique() %>% 
    stri_replace_all_regex("[R >=\\(\\)]", "") %>% 
    data_frame(vs=.) %>% 
    separate(vs, c("a", "b", "c"), fill="right") %>% 
    mutate(c=ifelse(is.na(c), 0, c)) %>% 
    arrange(a, b, c) %>% 
    tail(1) %>% 
    unite(min, a:c, sep=".") -> vs 

    return(vs$min) 

} 

# did we handle the edge cases well enought? 
base <- c("base", "compiler", "datasets", "grDevices", "graphics", "grid", "methods", "parallel", "profile", "splines", "stats", "stats4", "tcltk", "tools", "translations") 
(base_reqs <- purrr::map_chr(base, min_r_version)) 
## [1] "Unspecified" "Unspecified" "Unspecified" "Unspecified" "Unspecified" 
## [6] "Unspecified" "Unspecified" "Unspecified" "Unspecified" "Unspecified" 
## [11] "Unspecified" "Unspecified" "Unspecified" "Unspecified" "Unspecified" 

# a few of the "core" contributed pkgs rely on a pkg or two outside of base 
# but many only rely on base packages, to this is another gd edge case to 
# text for. 
contrib <- c("KernSmooth", "MASS", "Matrix", "boot", "class", "cluster", "codetools", "foreign", "lattice", "mgcv", "nlme", "nnet", "rpart", "spatial", "survival") 
contrib_reqs <- purrr::map_chr(contrib, min_r_version) 
## [1] "Unspecified" "Unspecified" "3.0.0"  "Unspecified" "3.1.0"  
## [6] "Unspecified" "Unspecified" "Unspecified" "Unspecified" "3.0.2"  
## [11] "3.0.0"  "Unspecified" "Unspecified" "Unspecified" "3.0.1"  

# See what the min version of R shld be for some of my pkgs 
min_r_version("ggalt") # I claim R (>= 3.0.0) in DESCRIPTION 
## [1] "3.1.2" 

min_r_version("curlconverter") # I claim R (>= 3.0.0) in DESCRIPTION 
## [1] "3.1.2" 

min_r_version("iptools") # I claim R (>= 3.0.0) in DESCRIPTION 
## [1] "3.0.0" 
+0

Vay. Çok teşekkürler. Bu, sorgulanan paketin kendisinin R gerekliliğini hariç tutuyor mu, çünkü değiştirmek istediğimiz değişken bu mu? –

+0

şuanda, bunu hariç tutuyorsak, belirli kenar durumlarıyla başa çıkmak için bazı “if-else” mantığı olması gerektiğinden, bu işlemi içerir, ancak bu işlemin temel mantığıdır. – hrbrmstr

+1

Güncel işlev belirtilen pkg'yi hariç tutmayı ve söz konusu kenar kasasını ele almayı destekler. Düşünmüyorum başka kenar vakaları olabilir. – hrbrmstr

0

@hrbrmstr gelen fikirler dayanarak ve baz fonksiyonları ile yazılı, şimdi aşağıdaki işlevi kullanıyorum: Ben bu projede önemli bir ilgi işe şüphe

min_r_version <- function(pkg) { 
    requireNamespace("tools") 
    requireNamespace("utils") 
    avail <- utils::available.packages(utils::contrib.url(repo)) 
    deps <- tools::package_dependencies(pkg, db = avail, recursive = TRUE) 
    if (is.null(deps)) 
    stop("package not found") 

    pkgs <- deps[[1]] 
    repo = getOption("repo") 
    if (is.null(repo)) 
    repo <- "https://cloud.r-project.org" 

    matches <- avail[ , "Package"] %in% pkgs 
    pkg_list <- avail[matches, "Depends"] 
    vers <- grep("^R$|^R \\(.*\\)$", pkg_list, value = TRUE) 
    vers <- gsub("[^0-9.]", "", vers) 
    if (length(vers) == 0) 
    return("Not specified") 

    max_ver = vers[1] 
    if (length(vers) == 1) 
    return(max_ver) 

    for (v in 2:length(vers)) 
    if (utils::compareVersion(vers[v], max_ver) > 0) 
     max_ver <- vers[v] 

    max_ver 
} 
İlgili konular