と呼ばれるAPIからデータを取得するために開発したパッケージを使用して、英国の公衆衛生機関から特定の地理的領域と特定の指標のデータを抽出しfingertipsR
、リストがリスト(地理)で構成される空のリストに挿入しています。 )各インジケーターを表すリストが含まれています。
geog <- c("E38000220", "E38000046", "E38000144", "E38000191", "E38000210",
"E38000038", "E38000164", "E38000195", "E38000078", "E38000139",
"E38000166", "E38000211", "E38000147", "E38000183", "E38000028",
"E38000053", "E38000126", "E38000153", "E38000173", "E38000175"
)
indicators <- c(241, 92588, 90672, 90692, 90697, 90698, 90701, 90702, 91238,
90690, 90694, 93245, 93246, 93244, 93247, 93248, 93049, 93047,
90700)
## install.packages("fingertipsR"); library(fingertipsR)
library(dplyr)
list <- list()
start <- Sys.time()
for (geog_group in geog) {
for (indicator_number in indicators) {
list[[geog_group]][[as.character(indicator_number)]] <- fingertips_data(IndicatorID = indicator_number, AreaTypeID = c(152, 153, 154)) %>%
filter(AreaCode == geog_group, TimeperiodSortable == max(TimeperiodSortable)) %>%
select(Timeperiod, Value) %>% distinct()
}
}
end <- Sys.time()
end-start
私の仕事用ラップトップでは、これを実行するのに約15分かかります-このコードを最適化する簡単な方法があるかどうか疑問に思っています-おそらくlapply
またはpurrr
?
編集:理想的には、各地理的領域のインジケーターが1つのデータフレームに含まれるようにします。これらはすべて同じ列Time period
を共有Value
し、後で処理する予定でしたunlist()
が、誰かがfor内でそれを解決する方法がある場合ループ私は提案を受け入れています。
これがより凝縮されたループです(約25秒かかります)。
result_list <- list(length(indicators))
for (k in seq_along(indicators)) {
ind <- indicators[k]
# load the data once per indicator
tmpDF <- fingertips_data(IndicatorID = ind, AreaTypeID = 152:154)
# retrieve the rows corresp. to max per geog
out <- t(vapply(seq_along(geog), function (s) {
row_geog <- which(.subset2(tmpDF, which(names(tmpDF) == 'AreaCode')) == geog[s])
row_max <- which.max(.subset2(tmpDF, which(names(tmpDF) == 'TimeperiodSortable'))[row_geog])
res <- tmpDF[row_geog,c("Timeperiod","Value")][row_max,]
res <- c(Timeperiod = res$Timeperiod, Value = res$Value)
if (length(res) == 0) res <- c(Timeperiod = NA_character_, Value = NA_character_)
return (res)
}, character(2)))
# save result for indicator[k]
result_list[[k]] <- data.frame(indicator = ind, geog,
Timeperiod = out[,1],
Value = as.numeric(out[,2]),
stringsAsFactors = FALSE)
}
私はあまり詳しくありませんfingertipsR
が、仕事は完了しているようです(間違っている場合は訂正してください)。結果の最初の要素は次のとおりです。
head(result_list[[1]])
# indicator geog Timeperiod Value
# 1 241 E38000220 2017/18 8.214912
# 2 241 E38000046 2017/18 7.907130
# 3 241 E38000144 2017/18 9.139239
# 4 241 E38000191 2017/18 8.891195
# 5 241 E38000210 2017/18 8.311592
# 6 241 E38000038 2017/18 6.653444
変更点
これが私があなたのバージョンから変更したものです:
for
ループを1つだけ作成しました(厳密に言えば、使用しているバージョンにはまだ2つのループがありますvapply
)。主な理由は、ループを少なくすることではなく(それ自体はすでに十分な動機付けです)、関数fingertips_data
をできるだけ少なく呼び出すことでした。これらの関数呼び出しは非常に遅く、依存せずgeog
、サブセット化のみが行います。indicator
の関数に対して1fingertips_data
回呼び出されvapply
、サブセットを使用して最大値を見つけることが行われます。この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加