我正在构建一个Shiny应用程序,其中需要使用大量外部源文件来一遍又一遍地计算大型ggplot2增强的数据帧。我正在寻找最快,最有效的方法。在下面的段落中,我将进一步研究到目前为止的主题和代码,并提供输入数据以帮助您提供帮助。
我使用的是赫尔辛基地区旅行时间矩阵2018,这是由赫尔辛基大学研究小组Digital Geography Lab提供的数据集。该数据使用赫尔辛基首都地区的广义地图,在250 x 250米的像元中(在我的代码grid_f
中),通过以下方式计算地图中所有像元之间的旅行时间(网格ID称为YKR_ID
,n = 13231)公共交通,私家车,自行车和步行。计算结果存储在定界的.txt文件中,该文本文件是到特定单元格ID的所有传播时间的一个文本文件。数据可供下载at this website, under "Download the data"。注意,解压缩后的数据大小为13.8 GB。
这里是从数据集中的文本文件中选择的内容:
from_id;to_id;walk_t;walk_d;bike_s_t;bike_f_t;bike_d;pt_r_tt;pt_r_t;pt_r_d;pt_m_tt;pt_m_t;pt_m_d;car_r_t;car_r_d;car_m_t;car_m_d;car_sl_t
5785640;5785640;0;0;-1;-1;-1;0;0;0;0;0;0;-1;0;-1;0;-1
5785641;5785640;48;3353;51;32;11590;48;48;3353;48;48;3353;22;985;21;985;16
5785642;5785640;50;3471;51;32;11590;50;50;3471;50;50;3471;22;12167;21;12167;16
5785643;5785640;54;3764;41;26;9333;54;54;3764;54;54;3764;22;10372;21;10370;16
5787544;5785640;38;2658;10;7;1758;38;38;2658;38;38;2658;7;2183;7;2183;6
[我的兴趣是使用ggplot2
可视化此250x250m赫尔辛基地区地图,用于一种行驶模式,即私家车,使用任何可能的13231个单元格ID(如果用户愿意),可以重复进行。因此,重要的是尽可能快且高效地提取数据帧。对于这个问题,让我们集中精力从外部文件中获取和处理数据,并仅使用一个特定的id值。
概括地说,在我生成250 x 250米网格空间数据集ggplot2::fortify()
的grid_f
版本之后,
from_id
,to_id
,car_r_t
,car_m_t
,car_sl_t
)>from_id
(在这种情况下为origin_id <- "5985086"
)选择相关行grid_f
我的代码如下:
# Libraries library(ggplot2) library(dplyr) library(rgdal) library(data.table) library(sf) library(sp) # File paths. ttm_path is the folder which contains the unchanged Travel # Time Matrix 2018 data from the research group's home page ttm_path <- "HelsinkiTravelTimeMatrix2018" gridpath <- "MetropAccess_YKR_grid_EurefFIN.shp" #### Import grid cells # use this CRS information throughout the app app_crs <- sp::CRS("+init=epsg:3067") # Read grid shapefile and transform grid_f <- rgdal::readOGR(gridpath, stringsAsFactors = TRUE) %>% sp::spTransform(., app_crs) %>% # preserve grid dataframe data in the fortify {dplyr::left_join(ggplot2::fortify(.), as.data.frame(.) %>% dplyr::mutate(id = as.character(dplyr::row_number() - 1)))} %>% dplyr::select(-c(x, y))
以上代码仅可运行一次。下面的代码或多或少会以不同的
origin_id
来重复运行。
#### Fetch TTM18 data origin_id <- "5985086" origin_id_num <- as.numeric(origin_id) # column positions of columns from_id, to_id, car_r_t, car_m_t, car_sl_t col_range <- c(1, 2, 14, 16, 18) # grid_f as data.table version dt_grid <- as.data.table(grid_f) # Get filepaths of all of the TTM18 data. Remove metadata textfile filepath. all_files <- list.files(path = ttm_path, pattern = ".txt$", recursive = TRUE, full.names = TRUE) all_files <- all_files[-length(all_files)] # lapply function TTM18_fetch <- function(x, col_range, origin_id) { res <- fread(x, select = col_range) res <- subset(res, from_id == origin_id) return(res) } # The part of the code that needs to be fast and efficient result <- lapply(all_files, FUN = TTM18_fetch, col_range, origin_id_num) %>% data.table::rbindlist(., fill = TRUE) %>% data.table::merge.data.table(dt_grid, ., by.x = "YKR_ID", by.y = "to_id")
数据框
result
应具有66155行的12个变量,每个250x250米的网格单元为5行。列为YKR_ID
,long
,lat
,order
,hole
,piece
,id
,group
,from_id
,car_r_t
,car_m_t
,car_sl_t
。
我当前的lapply()
和data.table::fread()
解决方案大约需要2-3分钟才能完成。我认为这已经是一个不错的成就,但是我无能为力,认为有更好,更快的方法可以完成此任务。到目前为止,我已经尝试了以下替代方法:
with()
失败,using this SO question,inspired by this SO questionparallel
包,但最终没有利用它apply()
和sapply()
的问题,但值得注意的是。>关于为什么我没有对ggplot2::fortify
之前的数据进行全部处理,我只是发现使用SpatialPolygonsDataFrame麻烦。
谢谢您的时间。
我正在构建一个Shiny应用程序,其中需要使用大量外部源文件来一遍又一遍地计算大型ggplot2增强的数据帧。我正在寻找最快的...
[无论何时我试图弄清楚如何提高R的性能功能上,我一般采用以下方法。首先,我寻找任何可能不必要的函数调用或标识多个位置的函数函数调用可以简化为一个。然后,我在我的地方寻找地方通过对每个代码进行基准测试而产生最大时间损失的代码分开分开。使用microbenchmark
package可以轻松完成此操作。
例如,我们可以问是否有更好的性能管道