微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

用于下载特定 csv 的通配符

如何解决用于下载特定 csv 的通配符

对 R 还是很陌生,所以请原谅。

我正在尝试从 Sloane 数字网站调查下载 csv 数据。在 R 中,我执行以下操作 -

astro1 <- read.csv("https://dr14.sdss.org/optical/spectrum/view/data/format=csv/spec=full?mjd=55359&fiberid=596&plateid=4055")

这会为每个板的每个光纤 ID 下载 1 个 csv 光谱 [此处,plateid=4055]。但是,如果有数百个光纤 ID,则需要很长时间。

  1. 有没有办法批量下载所有光纤 ID 的所有 csv 数据?我尝试了 fibreid=*(和“”、“”、@,但出现以下错误 -

    “输入中没有可用的行”,或意外的字符串常量。

  2. 例如,如果每个板有 100 个 .csv 文件。所有将有一个共同的 x 轴(波长),但不同的第 3 列(最适合,y 轴)。有没有办法让下载的 csv 表形成 1 个非常大的数据集,具有相同的公共轴(波长),随后的列仅显示最佳拟合列?

多谢

解决方法

最好的情况是你有一个你想要的 csv 文件的所有链接的列表。由于情况似乎并非如此,因此您知道要遍历所有 fiberid。你知道链接的结构,因此我们可以用它来定义

buildFibreIdLink <- function(fibreId) {
  paste0("https://dr14.sdss.org/optical/spectrum/view/data/format=csv/spec=full?mjd=55359&fiberid=",fibreId,"&plateid=4055")
}

现在我将循环遍历所有 id,无论在这种情况下意味着什么。只需从 1 开始计数。因此我会使用该功能

getCsvDataList <- function(startId = 1,endId = 10,maxConsecutiveNulls = 5) {
  
  dataList <- list()
  consecutiveNullCount <- 0
  
  for(id in startId:endId) {
    csvLink <- buildFibreIdLink(fibreId = id)
    newData <- tryCatch(expr = {
      read.csv(csvLink)
    },error = function(e) {return(NULL)})
    if(is.null(newData)) {
      consecutiveNullCount <- consecutiveNullCount +1
    } else {
      dataList <- c(dataList,list(newData))
      consecutiveNullCount <- 0
    }
    if(consecutiveNullCount == maxConsecutiveNulls) {
      print(paste0("reached maxConsecutiveNulls at id ",id))
      break;
    }
  }
  
  return(dataList)
}

指定要读取的 id-range,这样您就可以真正部分读取 csvs。现在的问题是:你什么时候到达终点?我的回答基本上是:当有 maxConsecutiveNulls 连续的“read-csv-fails”时,您就到了尽头。如果您无法阅读链接,我认为该链接不存在,因此 tryCatch-block 触发器,我基本上将这些触发器计数到给定的最大值。

如果你知道csvs的结构总是一样的,你可以通过

将data.frames列表合并在一起
dataListFrom1to10 <- getCsvDataList(startId = 1,endId = 10)
merged1to10 <- do.call("rbind",dataListFrom1to10)

更新:如果您有所需的光纤 ID 向量,则可以按如下方式修改该函数。由于我们不知道确切的 Id,我们从 1 循环到任何地方。现在,知道了 Id,您可以用 startId 替换 endIdfibreIdVector 参数,以获取签名 getCsvDataList <- function(fibreIdVector,maxConsecutiveNulls) ...。在 for 循环中,将 for(id in startId:endId) 替换为 for(id in fibreIdVector)。如果您知道所有 Id 都是有效的,则可以删除错误处理以获得更清晰的功能。由于您不需要知道先前迭代的结果,例如计算 consecutiveNullCount,您可以将所有内容放入 lapply 中,例如

allCsvData <- lapply(fibreIdVector,function(id) {
  read.csv(buildFibreIdLink(fibreId = id))
})

替换整个函数。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。