不论操作系统如何,如何使CRAN软件包仅下载一次数据?

问题描述

CRAN policy limits R package size to 5 Mb,对于诸如映射之类的图形应用程序几乎没有。有多种处理包装尺寸限制的方法,所有这些方法都有其缺点。备选方案已在下面列出。

我的问题是:如何使R包仅下载一次数据文件(即将它们保存到R重新启动后可以找到它们的位置)?该解决方案应适用于所有常见的CRAN平台。

我一直在开发mapping package for R,它应该在ggplot2中的全球任何地方绘制测深图。我列出了处理遇到的CRAN包中的大数据文件的替代方法。这些替代方法是考虑到书面地图制作的,但是适用于需要大的单个文件的情况:

  1. 移动large files to a data package并使原始数据包取决于数据数据包。

    • a)如果数据包小于5 Mb,则可以将其上载到CRAN,并且可以使原始数据包依赖或将其导入DESCRIPTION字段中。用户可以像使用任何其他CRAN包一样简单地使用install.packages()函数。事情运转得很奇妙,每个人都很高兴。
    • b)如果数据包> 5 Mb,情况会变得混乱。从理论上讲,一种替代方法是为每个文件创建单独的数据包,前提是数据文件均小于5 Mb。然后可以对每个数据包使用1a中的方法。这种选择太笨拙了,以至于我没有神经在实践中尝试它。在评论中听到有人是否有意思。
    • c)另一个更好的选择是使用drat package来制作data package,for example,to GitHub。这种选择的好处是用户可以编写install.packages()来从CRAN安装原始软件包,但对开发人员也有很多缺点。设置数据包以通过所有CRAN检查可能会有点挑战,因为目前尚未在线上任何地方正确指定所有步骤:原始数据包必须请求安装数据包的许可;数据包必须作为R的当前开发版本的单独二进制文件分发,至少在Windows和Mac上,在drat存储库中也可能用于Fedora。数据包应在描述文件的Suggests:下以Additional_repositories:的形式列出,并带有URL;提及到目前为止我遇到的一些惊喜。总而言之,这种替代方法对用户来说很棒,但需要开发人员进行维护。
  2. 某些映射包(例如marmap)将数据从外部服务器下载到temporary files。这种方法的好处是CRAN要求易于满足,并且用户不必存储超出应用程序要求的更多数据。该方法还允许在下载功能中指定分辨率,这对于“缩放”地图非常有用。缺点是该过程肯定比简单地在本地存储地图数据要花费更多的时间。另一个缺点是地图数据需要以栅格格式分发(否则服务器必须裁剪矢量)。在编写本文时,矢量数据比栅格数据更易于处理R和ggplot2中的颜色和样式。由于元素不受分辨率的限制,向量还可以使图形更清晰。第三个缺点是(据我所知)下载方法必须针对临时文件(即,当R重新启动时它们会丢失),这是由于操作系统差异而在编写CRAN软件包时所致。据我所知,不允许将Rdata文件添加到已经下载的和现有的R包中,并且很难找到一个可下载适用于所有主要CRAN操作系统的数据的位置。

我一直一次又一次地被CRAN拒绝,因为我还没有解决数据下载问题。网上有一些帮助,但我认为此问题尚未得到充分解决。最佳解决方案将下载sp个矢量shapefile 根据需要制作地图(对象可以以.Rdata格式存储)。这将允许为某些经常需要的区域添加详细的地图。 shapefile可以存储在GitHub上,这样可以在开发过程中快速灵活地修改这些文件。

解决方法

您是否尝试过使用xz压缩来减小sysdata的大小?我相信默认值为gzip,压缩级别设置为6。如果在使用save()保存数据包数据时使用bzip2或xz压缩,R将结合使用这些压缩算法和9压缩级别。结果是您获得了较小的包装数据对象。

,

getNOAA.bathy()包中的marmap函数具有一个keep参数,默认为FALSE。如果设置为TRUE,则从NOAA服务器上的ETOPO1数据库下载的数据集将本地存储在当前R会话的工作目录中。参数Path允许用户指定数据集的保存位置(版本1.0.5,在GitHub上可用,但在CRAN上不可用)。

当用户调用getNOAA.bathy()时,该函数首先检查请求的数据是否在本地可用,无论是在当前工作目录中还是在用户提供的path中。如果是(相同的边界框和分辨率),则不查询NOAA服务器,而是加载本地数据文件。如果不是,则从NOAA服务器下载数据。恕我直言,此方法具有以下优点:

  1. 如果keep=FALSE:本地没有存储任何内容,这样可以避免在加载许多不同的测试数据集时在用户磁盘上添加过多的杂物。
  2. 如果keep=TRUE:数据存储在本地。下次,加载数据将更快(并且可以脱机完成),因为一切都在本地进行。
  3. 在脚本中,相同的getNOAA.bathy()函数用于首先从NOAA服务器下载数据并在可用时加载本地文件。用户不必担心手动保存数据,也不必更改脚本来下次加载本地数据,因为该功能会自动从最合适的源(Web服务器或内部磁盘)加载数据。
  4. 无需在包中打包任何繁重的数据。

据我所知,唯一的缺点是在Windows计算机上,路径限制为250个字符,这在生成用于保存数据的文件名时可能会造成一些麻烦。实际上,根据浮点算法,文件名可能会很长,具体取决于边界框和下载到NOAA服务器上的数据的分辨率。一种简单的解决方法是,在生成要保存的文件名称之前,将边界框的坐标(使用round()ceiling()floor()舍入到小数点后几位。>

,

总的来说,我不会太客气。我认为可能存在一些诱骗软件包的方法,以便在安装过程中在线加载其他数据并将其添加到软件包本身。会以某种方式很好-但我认为它在CRAN维护人员中并不受欢迎。

以下内容如何? :

  1. 用于功能的CRAN软件包
  2. Github数据包

在CRAN软件包中,您导入devtools,并使用.onLoad方法,在devtools::install_github中安装G​​ithub数据软件包。 (当程序包使用library()/ require()加载时,将在加载时调用)。您有时会在软件包启动消息中看到这一点。

我可以想象以下优点:

  • 不是在安装过程中完成的,而是在程序包加载时完成的
  • 以某种方式对用户更透明(尤其是在您发送消息时)
  • 只能执行一次(加载后可以仅检查数据包是否存在并加载)
  • 数据实际上在软件包中,而不是用户路径
  • 数据加载后即可离线使用
  • 如果您在.onLoad中检查数据包的版本,也可以触发/更新数据而无需更新CRAN包

一个实现可能看起来像这样:

#' @import devtools
  
.onLoad <- function(libname,pkgname){
  if (! "wordcloud" %in% utils::installed.packages()) {
    message("installing data super dupa data package")
    devtools::install_github("ifellows/wordcloud")
  }
  else {
    require(wordcloud)
    message("Everything fine,ready for usage!")
  }
}

.onLoad必须位于您的任何.R文件中。对于您的具体实现,您还可以进一步完善它。我与wordcloud软件包没有任何关系-只是我很快在GitHub上找到的第一件事,作为使用install_github进行安装的示例。 如果出现错误消息说明分阶段安装,则必须将StagedInstall: no添加到DESCRIPTION文件中。

,

您可以具有将数据安装在选定位置的功能,并将路径存储在.R配置文件option(yourpackage.datapath = your path)中定义的选项中。您可能建议用户将其存储在软件包安装路径中。

安装功能首先打印上面的代码,并建议您在下载数据时将其复制并粘贴到.RProfile中:

if(is.null(getOption("yourpackage.datapath")))
  stop('you have not defined the "yourpackage.datapath" option,please make sure the data is installed using `yourpackage::install_yourdata",then copy `option(yourpackage.datapath = yourpath)` to your R profile.')

例如,您也可以使用edit()打开它。或将其放在您的pastebin中,但您不需要额外的依赖关系,我认为您需要一些帮助。我认为CRAN不会让您自动编辑.RProfile,但这对手动操作来说还算不错。安装功能可以在下载之前检查该选项是否已设置。

数据可以存储在名称空间的全局变量中。您只需要在包中定义一个环境对象和一个修改它的函数:

globals <- new.env()
load_data <- function(path) globals$data <- readRDS(path) 

然后,您的函数将在加载数据(检查路径选项是否设置正确)或继续运行之前测试globals$data是否为NULL

完成后,只要不删除数据或RProfile,它将永远有效,如果删除了数据或RProfile,则函数会捕获它并提供有关如何解决此问题的说明。


这里的另一个选项是将数据加载到.onLoad中,这意味着您将具有一些逻辑来处理首次加载程序包的情况。由于.onLoad通过libname参数知道安装路径,因此您甚至可以强行将数据下载到那里,然后在检查数据到那里后立即加载它(使用上述全局变量),因此不需要选项和RProfile。

只要提示用户,我认为使用CRAN就可以了。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...