最好的情况是您拥有指向所需 csv 文件的所有链接的列表。由于情况似乎并非如此,因此您知道您想要遍历所有fiberids。您知道链接的结构,因此我们可以使用它来定义
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,以便您可以真正部分读取 csv。现在的问题是:你什么时候到达终点?我的回答基本上是:当有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 和 endId 参数替换为 fibreIdVector,以获得签名
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))
})
替换整个函数。