R for 循环表示 ftp 地址中的变量



我想从ftp服务器获取多个zip文件。 我可以在以前的帖子的帮助下单独获取zip文件。

但对于所有需要的数据来说,这将是大量的工作。所以我想找到一种自动化的方法。

ftp 如下所示: ftp://ftp-cdc.dwd.de/pub/CDC/observations_germany/climate/10_minutes/solar/now/10minutenwerte_SOLAR_01048_now.zip

我想将"01048"更改为最近的加热器站的 ID,因为我已经在数据框(数据(中了。

我以为我可以循环所有需要的电台

for(y in Data$StationsID)) {
urls <- "ftp://ftp-cdc.dwd.de/pub/CDC/observations_germany/climate/10_minutes/solar/now/10minutenwerte_SOLAR_{y}_now.zip"))
}

但我只得到"ftp://ftp-cdc.dwd.de/pub/CDC/observations_germany/climate/10_minutes/solar/now/10minutenwerte_SOLAR_{y}_now.zip"((

ZIP 数据具有 .txt CSV 分析的理想选择。

稍后我想使用这些文件从德国的不同点获取太阳能数据。 但首先我需要这样的列表,但我不知道如何获得它:

urls
[1] url_1
[2] url_2
.
.

你甚至不需要循环。尝试

urls <- paste0("ftp://ftp-cdc.dwd.de/pub/CDC/observations_germany/climate/10_minutes/solar/now/10minutenwerte_SOLAR_", Data$StationsID, "_now.zip")

这将为您提供所有URL的向量。 之后,您可以使用例如lapply.

results <- lapply(urls, FUN = function(u) {
# FETCH
# UNZIP
# TIDY
# ...
}

(👍🏼第一个问题!

另一种方法如下。

我们:

  • 获取所有可能的数据文件
  • 仅将其过滤为SOLAR zip数据文件(如果需要,您可以过滤更多 - 即将其限制为现有数据框中的内容(
  • 创建保存位置
  • 下载文件

请注意,在没有暂停的情况下用连续的请求锤击服务器是非常糟糕的形式,所以这引入了它,但这是这些天经常被忽视的礼貌。

library(curl)
library(httr)
base_dir <- "ftp://ftp-cdc.dwd.de/pub/CDC/observations_germany/climate/10_minutes/solar/now/"
# Get all available files in that directory
res <- curl_fetch_memory(base_dir, handle = new_handle(dirlistonly = TRUE)
grep(
"SOLAR_[[:digit:]]{5}",
strsplit(rawToChar(res$content), "n")[[1]], # curl_fetch returns a raw vector since it has no idea what type of content might be there so we have to convert it and it's a text listing so we have to do some more wrangling
value = TRUE
) -> all_zips
head(all_zips)
## [1] "10minutenwerte_SOLAR_00044_now.zip"
## [2] "10minutenwerte_SOLAR_00071_now.zip"
## [3] "10minutenwerte_SOLAR_00073_now.zip"
## [4] "10minutenwerte_SOLAR_00131_now.zip"
## [5] "10minutenwerte_SOLAR_00150_now.zip"
## [6] "10minutenwerte_SOLAR_00154_now.zip"
save_dir <- "~/Data/solar-output"
dir.create(save_dir)
for (zip in all_zips) {
try(httr::GET(
url = sprintf("%s%s", base_dir, zip),
httr::write_disk(file.path(save_dir, zip)), # enables caching (it won't overwrite by default and avoid issues with download.file() on windows)
httr::progress() # progress bars for free!
))
Sys.sleep(5) # be kind to their server CPU and network bandwidth
}

我们将GET()包装在try()中,因为我们要求write_disk()不要覆盖现有文件。发生这种情况时,它会抛出一个异常,以便try()捕获它并让循环继续(但仍显示有关文件已存在的有用消息(。

最新更新