Вот подход с использованием базы R и lapply()
с анонимной функцией для загрузки данных, считывания их во фрейм данных, добавления преобразований в градусы Фаренгейта и накопления осадков и записи в выходные файлы.
Сначала мы создадим список метеостанций, для которых мы будем загружать данные
# list of 10 stations
stationList <- c("NE3065","NE8745","NE0030","NE0050","NE0130",
"NE0245","NE0320","NE0355","NE0375","NE0420")
Здесь мы создаем два фрагмента URL, один для содержимого URL до идентификатора станции, а другой один для содержимого URL после идентификатора станции.
urlFragment1 <- "https://mesonet.agron.iastate.edu/cgi-bin/request/coop.py?network=NECLIMATE&stations="
urlFragment2 <- "&year1=2020&month1=1&day1=1&year2=2020&month2=12&day2=31&vars%5B%5D=gdd_50_86&model=apsim&what=view&delim=comma&gis=no&scenario_year"
Затем мы создаем входные и выходные каталоги, один для хранения загруженных климатических входных файлов, а другой для выходных файлов.
# create input and output file directories if they do not already exist
if(!dir.exists("./data")) dir.create("./data")
if(!dir.exists("./data/output")) dir.create("./data/output")
Функция lapply()
использует paste0()
для добавления имен станций к фрагментам URL, которые мы создали выше, что позволяет нам автоматизировать загрузку и последующие операции с каждым входным файлом.
stationData <- lapply(stationList,function(x){
theURL <-paste0(urlFragment1,x,urlFragment2)
download.file(theURL,
paste0("./data/",x,".txt"),method="libcurl")
df <- read.table(paste0("./data/",x,".txt"), skip=11, stringsAsFactors =
FALSE)
colnames(df) <- c("year", "day", "solrad", "maxC",
"minC", "precipmm")
df$year <- as.factor(df$year)
df$day <- as.factor(df$day)
df$maxF <- (df$maxC * (9/5) + 32)
df$minF <- (df$minC * (9/5) + 32)
df$GDD <- (((df$maxF + df$minF)/2)-50)
df$GDD[df$GDD <= 0] <- 0
df$GDD.cumulative <- cumsum(df$GDD)
df$precipmm.cumulative <- cumsum(df$precipmm)
df$station <- x
write.table(df,file=paste0("./data/output/",x,".txt"), quote=FALSE,
row.names=FALSE, col.names=TRUE)
df
})
# add names to the data frames returned by lapply()
names(stationData) <- stationList
... и вывод, каталог, содержащий один файл для каждой станции, указанной в объекте stationList
.
Наконец, вот данные, которые были записаны в файл ./data/output/NE3065.txt
.
year day solrad maxC minC precipmm maxF minF GDD GDD.cumulateive precipmm.cumulative station
2020 1 8.992 2.2 -5 0 35.96 23 0 0 0 NE3065
2020 2 9.604 5.6 -3.9 0 42.08 24.98 0 0 0 NE3065
2020 3 4.933 5.6 -3.9 0 42.08 24.98 0 0 0 NE3065
2020 4 8.699 3.9 -7.2 0 39.02 19.04 0 0 0 NE3065
2020 5 9.859 6.1 -7.8 0 42.98 17.96 0 0 0 NE3065
2020 6 10.137 7.2 -5 0 44.96 23 0 0 0 NE3065
2020 7 8.754 6.1 -4.4 0 42.98 24.08 0 0 0 NE3065
2020 8 10.121 7.8 -5 0 46.04 23 0 0 0 NE3065
2020 9 9.953 7.2 -5 0 44.96 23 0 0 0 NE3065
2020 10 8.905 7.2 -5 0 44.96 23 0 0 0 NE3065
2020 11 0.416 -3.9 -15.6 2.29 24.98 3.92 0 0 2.29 NE3065
2020 12 10.694 -4.4 -16.1 0 24.08 3.02 0 0 2.29 NE3065
2020 13 1.896 -4.4 -11.1 0.51 24.08 12.02 0 0 2.8 NE3065
2020 14 0.851 0 -7.8 0 32 17.96 0 0 2.8 NE3065
2020 15 11.043 -1.1 -8.9 0 30.02 15.98 0 0 2.8 NE3065
2020 16 10.144 -2.8 -17.2 0 26.96 1.04 0 0 2.8 NE3065
2020 17 10.75 -5.6 -17.2 3.05 21.92 1.04 0 0 5.85 NE3065
Обратите внимание, что во входных файлах 11 строк данных заголовка, поэтому необходимо установить аргумент skip=
в read.table()
равным 11, а не 10, как это было использовано в OP.
Улучшение кода
Последняя строка в анонимной функции возвращает фрейм данных в родительскую среду, в результате получается список из 10 фреймов данных, хранящихся в объекте stationData
. Поскольку мы присвоили имя станции столбцу в каждом кадре данных, мы можем объединить кадры данных в один кадр данных для последующего анализа, используя do.call()
с rbind()
следующим образом.
combinedData <- do.call(rbind,stationData)
Поскольку этот код был запущен 17 января, результирующий кадр данных содержит 170 наблюдений или 17 наблюдений для каждой из 10 станций, чьи данные мы загрузили.
В этот момент данные можно анализировать по станциям, например, найти среднее количество осадков за год с каждой станции.
> aggregate(precipmm ~ station,combinedData,mean)
station precipmm
1 NE0030 0.01470588
2 NE0050 0.56764706
3 NE0130 0.32882353
4 NE0245 0.25411765
5 NE0320 0.28411765
6 NE0355 1.49411765
7 NE0375 0.55235294
8 NE0420 0.13411765
9 NE3065 0.34411765
10 NE8745 0.47823529
>